diff --git a/src/Entity/Key.php b/src/Entity/Key.php
index 2a58e1a..69b1713 100644
--- a/src/Entity/Key.php
+++ b/src/Entity/Key.php
@@ -10,6 +10,7 @@ namespace Drupal\key\Entity;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
+use Drupal\key\Exception\KeyValueNotSetException;
 use Drupal\key\KeyInterface;
 use Drupal\key\Plugin\KeyPluginCollection;
 use Drupal\key\Plugin\KeyProviderSettableValueInterface;
@@ -116,6 +117,13 @@ class Key extends ConfigEntityBase implements KeyInterface, EntityWithPluginColl
   protected $key_input_settings = [];
 
   /**
+   * The key value.
+   *
+   * @var string|NULL
+   */
+  protected $keyValue = NULL;
+
+  /**
    * The plugin collections, indexed by plugin type.
    *
    * @var \Drupal\key\Plugin\KeyPluginCollection[]
@@ -260,8 +268,15 @@ class Key extends ConfigEntityBase implements KeyInterface, EntityWithPluginColl
    * {@inheritdoc}
    */
   public function setKeyValue($key_value) {
+    $this->keyValue = $key_value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteKeyValue() {
     if ($this->getKeyProvider() instanceof KeyProviderSettableValueInterface) {
-      return $this->getKeyProvider()->setKeyValue($this, $key_value);
+      return $this->getKeyProvider()->deleteKeyValue($this);
     }
     else {
       return FALSE;
@@ -271,13 +286,29 @@ class Key extends ConfigEntityBase implements KeyInterface, EntityWithPluginColl
   /**
    * {@inheritdoc}
    */
-  public function deleteKeyValue() {
+  public function preSave(EntityStorageInterface $storage) {
+    // If the key provider supports setting a key value.
     if ($this->getKeyProvider() instanceof KeyProviderSettableValueInterface) {
-      return $this->getKeyProvider()->deleteKeyValue($this);
+      // If the provider requires a key value, but it is either not set
+      // or empty, throw an exception.
+      if ($this->getKeyProvider()->getPluginDefinition()['key_value']['required'] && (is_null($this->keyValue) || $this->keyValue === '')) {
+        throw new KeyValueNotSetException('The selected key provider requires a key value.');
+      }
+
+      // If a key value was defined, set the key value using the key provider.
+      if (isset($this->keyValue)) {
+        $this->getKeyProvider()->setKeyValue($this, $this->keyValue);
+      }
     }
+    // If the key provider does not support setting a value.
     else {
-      return FALSE;
+      // If a key value was defined, throw an exception.
+      if (isset($this->keyValue)) {
+        throw new KeyValueNotSetException('The selected key provider does not support setting a key value.');
+      }
     }
+
+    parent::preSave($storage);
   }
 
   /**
diff --git a/src/Exception/KeyException.php b/src/Exception/KeyException.php
new file mode 100644
index 0000000..008b313
--- /dev/null
+++ b/src/Exception/KeyException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\key\Exception\KeyException.
+ */
+
+namespace Drupal\key\Exception;
+
+/**
+ * Defines a generic exception for Key.
+ */
+class KeyException extends \Exception { }
diff --git a/src/Exception/KeyValueNotSetException.php b/src/Exception/KeyValueNotSetException.php
new file mode 100644
index 0000000..2fa6fa3
--- /dev/null
+++ b/src/Exception/KeyValueNotSetException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\key\Exception\KeyValueNotSetException.
+ */
+
+namespace Drupal\key\Exception;
+
+/**
+ * Defines an exception for when a key value fails to be set.
+ */
+class KeyValueNotSetException extends KeyException { }
diff --git a/src/Form/KeyAddForm.php b/src/Form/KeyAddForm.php
index 9e52716..c361907 100644
--- a/src/Form/KeyAddForm.php
+++ b/src/Form/KeyAddForm.php
@@ -34,12 +34,4 @@ class KeyAddForm extends KeyFormBase {
     return parent::buildForm($form, $form_state);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    parent::submitForm($form, $form_state);
-    drupal_set_message($this->t('The key %label has been added.', array('%label' => $this->entity->label())));
-  }
-
 }
diff --git a/src/Form/KeyEditForm.php b/src/Form/KeyEditForm.php
index f0351db..57ad8be 100644
--- a/src/Form/KeyEditForm.php
+++ b/src/Form/KeyEditForm.php
@@ -72,12 +72,4 @@ class KeyEditForm extends KeyFormBase {
     return parent::form($form, $form_state);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    parent::submitForm($form, $form_state);
-    drupal_set_message($this->t('The key %label has been updated.', array('%label' => $this->entity->label())));
-  }
-
 }
diff --git a/src/Form/KeyFormBase.php b/src/Form/KeyFormBase.php
index e3f7fb7..03e6d1c 100644
--- a/src/Form/KeyFormBase.php
+++ b/src/Form/KeyFormBase.php
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\key\Entity\Key;
+use Drupal\key\Exception\KeyValueNotSetException;
 use Drupal\key\Plugin\KeyPluginFormInterface;
 use Drupal\key\Plugin\KeyProviderSettableValueInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -260,7 +261,7 @@ abstract class KeyFormBase extends EntityForm {
     // Allow the Key Type plugin to validate the key value. Use the processed
     // key value if there is one. Otherwise, retrieve the key value using the
     // key provider.
-    if (!empty($processed_values['processed_submitted'])) {
+    if (isset($processed_values['processed_submitted'])) {
       $key_value = $processed_values['processed_submitted'];
     }
     else {
@@ -292,11 +293,27 @@ abstract class KeyFormBase extends EntityForm {
 
     // If the key provider allows a key value to be set.
     if ($this->entity->getKeyProvider() instanceof KeyProviderSettableValueInterface) {
-      // If either the key provider has changed or the submitted value
-      // is not the same as the obscured value.
-      if (($this->originalKey && $this->originalKey->getKeyProvider()->getPluginId() != $this->entity->getKeyProvider()->getPluginId())
-        || ($key_value_data['submitted'] != $key_value_data['obscured'])) {
-        // Set the key value.
+      $set_key_value = FALSE;
+
+      // If the key provider has changed, the key value should be set.
+      if ($this->originalKey && $this->originalKey->getKeyProvider()->getPluginId() != $this->entity->getKeyProvider()->getPluginId()) {
+        $set_key_value = TRUE;
+      }
+
+      // If the submitted value is not the same as the obscured value,
+      // the key value should be set.
+      if ($key_value_data['submitted'] != $key_value_data['obscured']) {
+        $set_key_value = TRUE;
+      }
+
+      // If the processed value is not empty, but the submitted value is,
+      // the key value should be set.
+      if (!empty($key_value_data['processed_original']) && empty($key_value_data['submitted'])) {
+        $set_key_value = TRUE;
+      }
+
+      // Set the key value in the entity, if necessary.
+      if ($set_key_value) {
         $this->entity->setKeyValue($key_value_data['processed_submitted']);
       }
     }
@@ -308,7 +325,27 @@ abstract class KeyFormBase extends EntityForm {
    * {@inheritdoc}
    */
   public function save(array $form, FormStateInterface $form_state) {
-    parent::save($form, $form_state);
+    /* @var $key \Drupal\key\Entity\Key */
+    $key = $this->entity;
+
+    // Save the key, catching exceptions.
+    try {
+      $status = $key->save();
+    }
+    catch (KeyValueNotSetException $e) {
+      drupal_set_message($this->t('The key was not saved because the key value could not be set. @message', array('@message' => $e->getMessage())), 'error');
+      return;
+    }
+
+    $t_args = array('%name' => $key->label());
+
+    if ($status == SAVED_UPDATED) {
+      drupal_set_message($this->t('The key %name has been updated.', $t_args));
+    }
+    elseif ($status == SAVED_NEW) {
+      drupal_set_message(t('The key %name has been added.', $t_args));
+    }
+
     $form_state->setRedirectUrl($this->entity->toUrl('collection'));
   }
 
diff --git a/src/Plugin/KeyInputBase.php b/src/Plugin/KeyInputBase.php
index 259bf63..3aa36d8 100644
--- a/src/Plugin/KeyInputBase.php
+++ b/src/Plugin/KeyInputBase.php
@@ -42,8 +42,9 @@ abstract class KeyInputBase extends KeyPluginBase implements KeyInputInterface,
     $key_input_settings = $form_state->getValues();
     $key_value_data = $form_state->get('key_value');
     if (isset($key_input_settings['key_value'])) {
-      // If the submitted key value is equal to the obscured value.
-      if ($key_input_settings['key_value'] == $key_value_data['obscured']) {
+      // If the submitted key value is not empty and equal to the obscured
+      // value.
+      if (!empty($key_input_settings['key_value']) && $key_input_settings['key_value'] == $key_value_data['obscured']) {
         // Use the processed original value as the submitted value.
         $processed_values['submitted'] = $key_value_data['processed_original'];
       }
diff --git a/src/Plugin/KeyProvider/ConfigKeyProvider.php b/src/Plugin/KeyProvider/ConfigKeyProvider.php
index 52882df..cd362c5 100644
--- a/src/Plugin/KeyProvider/ConfigKeyProvider.php
+++ b/src/Plugin/KeyProvider/ConfigKeyProvider.php
@@ -8,6 +8,7 @@
 namespace Drupal\key\Plugin\KeyProvider;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\key\Exception\KeyValueNotSetException;
 use Drupal\key\Plugin\KeyProviderBase;
 use Drupal\key\Plugin\KeyPluginFormInterface;
 use Drupal\key\Plugin\KeyProviderSettableValueInterface;
@@ -94,7 +95,7 @@ class ConfigKeyProvider extends KeyProviderBase implements KeyPluginFormInterfac
       return TRUE;
     }
     else {
-      return FALSE;
+      throw new KeyValueNotSetException();
     }
   }
 
