diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
index 9a5cbde..1e9e906 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
@@ -36,6 +36,13 @@ class SettingsForm extends SystemConfigFormBase {
   );
 
   /**
+   * The instanciated plugin instances.
+   *
+   * @var array
+   */
+  protected $instances = array();
+
+  /**
    * Constructs a \Drupal\aggregator\SettingsForm object.
    *
    * @param \Drupal\Core\Config\ConfigFactory $config_factory
@@ -82,7 +89,7 @@ public function getFormID() {
   }
 
   /**
-   * Implements \Drupal\Core\Form\FormInterface::buildForm().
+   * {@inheritdoc}
    */
   public function buildForm(array $form, array &$form_state) {
     $config = $this->configFactory->get('aggregator.settings');
@@ -136,28 +143,52 @@ public function buildForm(array $form, array &$form_state) {
       $form['basic_conf'] += $basic_conf;
     }
 
+    // Call settingsForm() on the active fetcher and parser.
+    foreach (array('fetcher', 'parser') as $type) {
+      $active = $config->get($type);
+      if (array_key_exists($active, $this->definitions[$type])) {
+        $instance = $this->managers[$type]->createInstance($active);
+        $form = $instance->settingsForm($form, $form_state);
+        // Store the instance for validate and submit handlers.
+        $this->instances[] = $instance;
+      }
+    }
+
     // Implementing processor plugins will expect an array at $form['processors'].
     $form['processors'] = array();
     // Call settingsForm() for each active processor.
     foreach ($this->definitions['processor'] as $id => $definition) {
       if (in_array($id, $config->get('processors'))) {
-        $form = $this->managers['processor']->createInstance($id)->settingsForm($form, $form_state);
+        $instance = $this->managers['processor']->createInstance($id);
+        $form = $instance->settingsForm($form, $form_state);
+        // Store the instance for validate and submit handlers.
+        $this->instances[] = $instance;
       }
     }
     return parent::buildForm($form, $form_state);
   }
 
   /**
-   * Implements \Drupal\Core\Form\FormInterface::submitForm().
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {
+    parent::validateForm($form, $form_state);
+    // Let active plugins validate their settings.
+    foreach ($this->instances as $instance) {
+      $instance->settingsValidate($form, $form_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
    */
   public function submitForm(array &$form, array &$form_state) {
     parent::submitForm($form, $form_state);
     $config = $this->configFactory->get('aggregator.settings');
-    // Let active processors save their settings.
-    foreach ($this->definitions['processor'] as $id => $definition) {
-      if (in_array($id, $config->get('processors'))) {
-        $this->managers['processor']->createInstance($id)->settingsSubmit($form, $form_state);
-      }
+
+    // Let active plugins save their settings.
+    foreach ($this->instances as $instance) {
+      $instance->settingsSubmit($form, $form_state);
     }
 
     $config->set('items.allowed_html', $form_state['values']['aggregator_allowed_html_tags']);
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
new file mode 100644
index 0000000..a7757ba
--- /dev/null
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\aggregator\Plugin\AggregatorPluginSettingsBase.
+ */
+
+namespace Drupal\aggregator\Plugin;
+
+use Drupal\Component\Plugin\PluginBase;
+
+/**
+ * Base class for aggregator's plugin implementations.
+ */
+abstract class AggregatorPluginSettingsBase extends PluginBase implements AggregatorPluginSettingsInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsValidate(array $form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSubmit(array $form, array &$form_state) {}
+
+}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsInterface.php
new file mode 100644
index 0000000..d9310f0
--- /dev/null
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsInterface.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\aggregator\Plugin\AggregatorPluginSettingsInterface.
+ */
+
+namespace Drupal\aggregator\Plugin;
+
+/**
+ * Interface definition for aggregator plugins with settings.
+ */
+interface AggregatorPluginSettingsInterface {
+
+  /**
+   * Returns a form to configure settings for the plugin.
+   *
+   * @param array $form
+   *   The form definition array where the settings form is being included in.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @return array
+   *   The form elements for the plugin settings.
+   *
+   * @see \Drupal\aggregator\Plugin\AggregatorPluginSettingsInterface::settingsValidate()
+   * @see \Drupal\aggregator\Plugin\AggregatorPluginSettingsInterface::settingsSubmit()
+   */
+  public function settingsForm(array $form, array &$form_state);
+
+  /**
+   * Adds plugin specific validation handling for the configuration form.
+   *
+   * @param array $form
+   *   The form definition array where the settings form is being included in.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @see \Drupal\aggregator\Plugin\AggregatorPluginSettingsInterface::settingsSubmit()
+   */
+  public function settingsValidate(array $form, array &$form_state);
+
+  /**
+   * Adds plugin specific submission handling for the configuration form.
+   *
+   * @param array $form
+   *   The form definition array where the settings form is being included in.
+   * @param array $form_state
+   *   An associative array containing the current state of the form.
+   *
+   * @see \Drupal\aggregator\Plugin\AggregatorPluginSettingsInterface::settingsValidate()
+   */
+  public function settingsSubmit(array $form, array &$form_state);
+
+}
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php
index da1377d..02869d2 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/FetcherInterface.php
@@ -18,7 +18,7 @@
  * parser; and finally, it is passed to all active processors, which manipulate
  * or store the data.
  */
-interface FetcherInterface {
+interface FetcherInterface extends AggregatorPluginSettingsInterface {
 
   /**
    * Downloads feed data.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ParserInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ParserInterface.php
index 317b806..f3900a9 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ParserInterface.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ParserInterface.php
@@ -19,7 +19,7 @@
  * manipulate or store the data.
  *
  */
-interface ParserInterface {
+interface ParserInterface extends AggregatorPluginSettingsInterface {
 
   /**
    * Parses feed data.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
index b670383..a6d50fe 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/ProcessorInterface.php
@@ -18,32 +18,7 @@
  * parser; and finally, it is passed to all active processors that manipulate or
  * store the data.
  */
-interface ProcessorInterface {
-
-  /**
-   * Returns a form to configure settings for the processor.
-   *
-   * @param array $form
-   *   The form definition array where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @return array
-   *   The form elements for the processor settings.
-   */
-  public function settingsForm(array $form, array &$form_state);
-
-  /**
-   * Adds processor specific submission handling for the configuration form.
-   *
-   * @param array $form
-   *   The form definition array where the settings form is being included in.
-   * @param array $form_state
-   *   An associative array containing the current state of the form.
-   *
-   * @see \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm()
-   */
-  public function settingsSubmit(array $form, array &$form_state);
+interface ProcessorInterface extends AggregatorPluginSettingsInterface {
 
   /**
    * Processes feed data.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
index e71412b..7a9c441 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/fetcher/DefaultFetcher.php
@@ -8,6 +8,7 @@
 namespace Drupal\aggregator\Plugin\aggregator\fetcher;
 
 use Drupal\aggregator\Plugin\FetcherInterface;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
@@ -25,10 +26,10 @@
  *   description = @Translation("Downloads data from a URL using Drupal's HTTP request handler.")
  * )
  */
-class DefaultFetcher implements FetcherInterface {
+class DefaultFetcher extends AggregatorPluginSettingsBase implements FetcherInterface {
 
   /**
-   * Implements \Drupal\aggregator\Plugin\FetcherInterface::fetch().
+   * {@inheritdoc}
    */
   public function fetch(Feed $feed) {
     // @todo: Inject the http client.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
index 0086bac..4fb323a 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/parser/DefaultParser.php
@@ -8,6 +8,7 @@
 namespace Drupal\aggregator\Plugin\aggregator\parser;
 
 use Drupal\aggregator\Plugin\ParserInterface;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
@@ -23,7 +24,7 @@
  *   description = @Translation("Default parser for RSS, Atom and RDF feeds.")
  * )
  */
-class DefaultParser implements ParserInterface {
+class DefaultParser extends AggregatorPluginSettingsBase implements ParserInterface {
 
   /**
    * The extracted channel info.
@@ -68,7 +69,7 @@ class DefaultParser implements ParserInterface {
   protected $item;
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ParserInterface::parse().
+   * {@inheritdoc}
    */
   public function parse(Feed $feed) {
     // Filter the input data.
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
index 08777d1..1602059 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php
@@ -7,8 +7,8 @@
 
 namespace Drupal\aggregator\Plugin\aggregator\processor;
 
-use Drupal\Component\Plugin\PluginBase;
 use Drupal\aggregator\Plugin\ProcessorInterface;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
 use Drupal\Core\Annotation\Translation;
@@ -25,10 +25,10 @@
  *   description = @Translation("Creates lightweight records from feed items.")
  * )
  */
-class DefaultProcessor extends PluginBase implements ProcessorInterface {
+class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm().
+   * {@inheritdoc}.
    */
   public function settingsForm(array $form, array &$form_state) {
     $config = config('aggregator.settings');
@@ -84,7 +84,7 @@ public function settingsForm(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit().
+   * {@inheritdoc}
    */
   public function settingsSubmit(array $form, array &$form_state) {
     $config = config('aggregator.settings');
@@ -96,7 +96,7 @@ public function settingsSubmit(array $form, array &$form_state) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process().
+   * {@inheritdoc}
    */
   public function process(Feed $feed) {
     if (!is_array($feed->items)) {
@@ -147,7 +147,7 @@ public function process(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::remove().
+   * {@inheritdoc}
    */
   public function remove(Feed $feed) {
     $iids = Database::getConnection()->query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->id()))->fetchCol();
@@ -159,9 +159,7 @@ public function remove(Feed $feed) {
   }
 
   /**
-   * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
-   *
-   * Expires items from a feed depending on expiration settings.
+   * {@inheritdoc}
    */
   public function postProcess(Feed $feed) {
     $aggregator_clear = config('aggregator.settings')->get('items.expire');
diff --git a/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
index 3ffe213..3d767a4 100644
--- a/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
+++ b/core/modules/aggregator/tests/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\aggregator_test\Plugin\aggregator\processor;
 
-use Drupal\Component\Plugin\PluginBase;
+use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
 use Drupal\aggregator\Plugin\ProcessorInterface;
 use Drupal\aggregator\Plugin\Core\Entity\Feed;
 use Drupal\Component\Annotation\Plugin;
@@ -24,7 +24,7 @@
  *   description = @Translation("Test generic processor functionality.")
  * )
  */
-class TestProcessor extends PluginBase implements ProcessorInterface {
+class TestProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
 
   /**
    * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm().
