diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index 8e14b36..a3b6c62 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -18,21 +18,23 @@ uri:
   label: 'Uri'
   class: '\Drupal\Core\TypedData\Plugin\DataType\Uri'
 
-# Basic data types for configuration.
+# Undefined type to use for missing schema, don't use explicitly.
 undefined:
   label: 'Undefined'
-  class: '\Drupal\Core\Config\Schema\Property'
-mapping:
-  label: Mapping
-  class: '\Drupal\Core\Config\Schema\Mapping'
+  class: '\Drupal\Core\Config\Schema\Undefined'
+
+# Explicit type when no data typing is possible. Avoid if at all possible.
+ignore:
+  label: 'Ignore'
+  class: '\Drupal\Core\Config\Schema\Ignore'
+
+# Container data types with lists with known and uknown keys.
 sequence:
   label: Sequence
   class: '\Drupal\Core\Config\Schema\Sequence'
-
-# Default mapping for unknown types or types not found.
-default:
-  type: undefined
-  label: 'Unknown'
+mapping:
+  label: Mapping
+  class: '\Drupal\Core\Config\Schema\Mapping'
 
 # Simple extended data types:
 
diff --git a/core/lib/Drupal/Core/Config/Schema/Ignore.php b/core/lib/Drupal/Core/Config/Schema/Ignore.php
new file mode 100644
index 0000000..20701b8
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Schema/Ignore.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\Schema\Ignore.
+ */
+
+namespace Drupal\Core\Config\Schema;
+
+/**
+ * Configuration property to ignore.
+ */
+class Ignore extends Element {
+
+  /**
+   * {@inheritdoc}.
+   */
+  public function validate() {
+    return TRUE;
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/Schema/Property.php b/core/lib/Drupal/Core/Config/Schema/Property.php
deleted file mode 100644
index d7e4b60..0000000
--- a/core/lib/Drupal/Core/Config/Schema/Property.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Config\Schema\Sequence.
- */
-
-namespace Drupal\Core\Config\Schema;
-
-/**
- * Generic configuration property.
- */
-class Property extends Element {
-
-  /**
-   * Implements TypedDataInterface::validate().
-   */
-  public function validate() {
-    return isset($this->value);
-  }
-
-}
diff --git a/core/lib/Drupal/Core/Config/Schema/Undefined.php b/core/lib/Drupal/Core/Config/Schema/Undefined.php
new file mode 100644
index 0000000..1bcf744
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Schema/Undefined.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Config\Schema\Undefined.
+ */
+
+namespace Drupal\Core\Config\Schema;
+
+/**
+ * Undefined configuration element.
+ */
+class Undefined extends Element {
+
+  /**
+   * {@inheritdoc}.
+   */
+  public function validate() {
+    return isset($this->value);
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php
index 18c0f07..e5b313d 100644
--- a/core/lib/Drupal/Core/Config/StorableConfigBase.php
+++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php
@@ -8,10 +8,12 @@
 namespace Drupal\Core\Config;
 
 use Drupal\Component\Utility\String;
+use Drupal\Core\Config\Schema\Ignore;
 use Drupal\Core\Config\Schema\SchemaIncompleteException;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
 use Drupal\Core\TypedData\Type\IntegerInterface;
+use Drupal\Core\Config\Schema\Undefined;
 
 /**
  * Provides a base class for configuration objects with storage support.
@@ -167,37 +169,34 @@ protected function validateValue($key, $value) {
    *   Exception on unsupported/undefined data type deducted.
    */
   protected function castValue($key, $value) {
-    if ($value === NULL) {
-      $value = NULL;
+    $element = FALSE;
+    try {
+      $element = $this->getSchemaWrapper()->get($key);
     }
-    elseif (is_scalar($value)) {
-      try {
-        $element = $this->getSchemaWrapper()->get($key);
-        if ($element instanceof PrimitiveInterface) {
-          // Special handling for integers and floats since the configuration
-          // system is primarily concerned with saving values from the Form API
-          // we have to special case the meaning of an empty string for numeric
-          // types. In PHP this would be casted to a 0 but for the purposes of
-          // configuration we need to treat this as a NULL.
-          if ($value === '' && ($element instanceof IntegerInterface || $element instanceof FloatInterface)) {
-            $value = NULL;
-          }
-          else {
-            $value = $element->getCastedValue();
-          }
+    catch (SchemaIncompleteException $e) {
+      // @todo throw an exception due to an incomplete schema.
+      // Fix as part of https://drupal.org/node/2183983.
+    }
+    // Do not cast value if it is unknown or defined to be ignored.
+    if ($element && ($element instanceof Undefined || $element instanceof Ignore)) {
+      return $value;
+    }
+    if ((is_scalar($value) || $value === NULL)) {
+      if ($element && $element instanceof PrimitiveInterface) {
+        // Special handling for integers and floats since the configuration
+        // system is primarily concerned with saving values from the Form API
+        // we have to special case the meaning of an empty string for numeric
+        // types. In PHP this would be casted to a 0 but for the purposes of
+        // configuration we need to treat this as a NULL.
+        $empty_value =  $value === '' && ($element instanceof IntegerInterface || $element instanceof FloatInterface);
+
+        if ($value === NULL || $empty_value) {
+          $value = NULL;
         }
         else {
-          // Config only supports primitive data types. If the config schema
-          // does define a type $element will be an instance of
-          // \Drupal\Core\Config\Schema\Property. Convert it to string since it
-          // is the safest possible type.
-          $value = $element->getString();
+          $value = $element->getCastedValue();
         }
       }
-      catch (SchemaIncompleteException $e) {
-        // @todo throw an exception due to an incomplete schema.
-        // Fix as part of https://drupal.org/node/2183983.
-      }
     }
     else {
       // Throw exception on any non-scalar or non-array value.
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index 647d00f..6fba132 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -152,9 +152,8 @@ public function getDefinition($base_plugin_id) {
       $type = $name;
     }
     else {
-      // If we don't have definition, return the 'default' element.
-      // This should map to 'undefined' type by default, unless overridden.
-      $type = 'default';
+      // If we don't have definition, return the 'undefined' element.
+      $type = 'undefined';
     }
     $definition = $definitions[$type];
     // Check whether this type is an extension of another one and compile it.
@@ -326,10 +325,9 @@ protected function replaceVariable($value, $data) {
    * {@inheritdoc}
    */
   public function hasConfigSchema($name) {
-    // The schema system falls back on the Property class for unknown types.
-    // See http://drupal.org/node/1905230
+    // The schema system falls back on the Undefined class for unknown types.
     $definition = $this->getDefinition($name);
-    return is_array($definition) && ($definition['class'] != '\Drupal\Core\Config\Schema\Property');
+    return is_array($definition) && ($definition['class'] != '\Drupal\Core\Config\Schema\Undefined');
   }
 
 }
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
index 173955f..1bef99c 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Config\InstallStorage;
 use Drupal\Core\TypedData\Type\IntegerInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
 use Drupal\simpletest\DrupalUnitTestBase;
@@ -40,15 +42,15 @@ public function setUp() {
    * Tests the basic metadata retrieval layer.
    */
   function testSchemaMapping() {
-    // Nonexistent configuration key will have Unknown as metadata.
+    // Nonexistent configuration key will have Undefined as metadata.
     $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.no_such_key'));
     $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.no_such_key');
     $expected = array();
-    $expected['label'] = 'Unknown';
-    $expected['class'] = '\Drupal\Core\Config\Schema\Property';
+    $expected['label'] = 'Undefined';
+    $expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
 
-    // Configuration file without schema will return Unknown as well.
+    // Configuration file without schema will return Undefined as well.
     $this->assertIdentical(FALSE, \Drupal::service('config.typed')->hasConfigSchema('config_schema_test.noschema'));
     $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.noschema');
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with no schema.');
@@ -68,13 +70,13 @@ function testSchemaMapping() {
     $definition = $config['testitem']->getDataDefinition();
     $expected = array();
     $expected['label'] = 'Test item';
-    $expected['class'] = '\Drupal\Core\Config\Schema\Property';
+    $expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
     $expected['type'] = 'undefined';
     $this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
     $definition = $config['testlist']->getDataDefinition();
     $expected = array();
     $expected['label'] = 'Test list';
-    $expected['class'] = '\Drupal\Core\Config\Schema\Property';
+    $expected['class'] = '\Drupal\Core\Config\Schema\Undefined';
     $expected['type'] = 'undefined';
     $this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
 
@@ -93,6 +95,40 @@ function testSchemaMapping() {
     );
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
 
+    // Mixed schema with ignore elements.
+    $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.ignore');
+    $expected = array();
+    $expected['label'] = 'Ignore test';
+    $expected['class'] = '\Drupal\Core\Config\Schema\Mapping';
+    $expected['mapping']['label'] = array(
+      'label' =>  'Label',
+      'type' => 'label',
+    );
+    $expected['mapping']['irrelevant'] = array(
+      'label' => 'Irrelevant',
+      'type' => 'ignore',
+    );
+    $expected['mapping']['indescribable'] = array(
+      'label' => 'Indescribable',
+      'type' => 'ignore',
+    );
+    $expected['mapping']['weight'] = array(
+      'label' => 'Weight',
+      'type' => 'integer',
+    );
+    $this->assertEqual($definition, $expected);
+
+    // The ignore elements themselves.
+    $definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('irrelevant')->getDataDefinition();
+    $expected = array();
+    $expected['type'] = 'ignore';
+    $expected['label'] = 'Irrelevant';
+    $expected['class'] = '\Drupal\Core\Config\Schema\Ignore';
+    $this->assertEqual($definition, $expected);
+    $definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition();
+    $expected['label'] = 'Indescribable';
+    $this->assertEqual($definition, $expected);
+
     // More complex case, generic type. Metadata for image style.
     $definition = \Drupal::service('config.typed')->getDefinition('image.style.large');
     $expected = array();
@@ -138,7 +174,7 @@ function testSchemaMapping() {
 
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium');
 
-    // More complex, multiple filesystem marker test.
+    // More complex, several level deep test.
     $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection');
     // This should be the schema of config_schema_test.someschema.somemodule.*.*.
     $expected = array();
@@ -254,7 +290,7 @@ public function testConfigSaveWithSchema() {
       'integer' => '100',
       'null_integer' => '',
       'boolean' => 1,
-      // If the config schema doesn't have a type it should be casted to string.
+      // If the config schema doesn't have a type it shouldn't be casted.
       'no_type' => 1,
       'mapping' => array(
         'string' => 1
@@ -277,7 +313,7 @@ public function testConfigSaveWithSchema() {
       'integer' => 100,
       'null_integer' => NULL,
       'boolean' => TRUE,
-      'no_type' => '1',
+      'no_type' => 1,
       'mapping' => array(
         'string' => '1'
       ),
@@ -300,6 +336,14 @@ public function testConfigSaveWithSchema() {
       ->setData($untyped_values)
       ->save();
     $this->assertIdentical(\Drupal::config('config_schema_test.no_schema_data_types')->get(), $untyped_values);
+
+    // Ensure that configuration objects with keys marked as ignored are not
+    // changed when saved. The 'config_schema_test.ignore' will have been saved
+    // during the installation of configuration in the setUp method.
+    $extension_path = drupal_get_path('module', 'config_schema_test');
+    $install_storage = new FileStorage($extension_path . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY);
+    $original_data = $install_storage->read('config_schema_test.ignore');
+    $this->assertIdentical(\Drupal::config('config_schema_test.ignore')->get(), $original_data);
   }
 
   /**
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTestBase.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTestBase.php
index b31551a..eac1a75 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTestBase.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTestBase.php
@@ -8,7 +8,6 @@
 namespace Drupal\config\Tests;
 
 use Drupal\Core\Config\Schema\ArrayElement;
-use Drupal\Core\Config\Schema\Property;
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\TypedData\Type\BooleanInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
@@ -84,36 +83,34 @@ public function assertConfigSchema(TypedConfigManagerInterface $typed_config, $c
    *   Returns mixed value.
    */
   protected function checkValue($key, $value) {
-
+    $element = FALSE;
     try {
       $element = $this->schema->get($key);
     }
     catch (SchemaIncompleteException $e) {
-      $this->fail("{$this->configName}:$key has no schema.");
+      if (is_scalar($value) || $value === NULL) {
+        $this->fail("{$this->configName}:$key has no schema.");
+      }
     }
+    // Do not check value if it is defined to be ignored.
+    if ($element && $element instanceof Ignore) {
+      return $value;
+    }
+
     if (is_scalar($value) || $value === NULL) {
       $success = FALSE;
       $type = gettype($value);
       if ($element instanceof PrimitiveInterface) {
-        if ($type == 'integer' && $element instanceof IntegerInterface) {
-          $success = TRUE;
-        }
-        if ($type == 'double' && $element instanceof FloatInterface) {
-          $success = TRUE;
-        }
-        if ($type == 'boolean' && $element instanceof BooleanInterface) {
-          $success = TRUE;
-        }
-        if ($type == 'string' && ($element instanceof StringInterface || $element instanceof Property)) {
-          $success = TRUE;
-        }
-        // Null values are allowed for all scalar types.
-        if ($value === NULL) {
-          $success = TRUE;
-        }
+        $success =
+          ($type == 'integer' && $element instanceof IntegerInterface) ||
+          ($type == 'double' && $element instanceof FloatInterface) ||
+          ($type == 'boolean' && $element instanceof BooleanInterface) ||
+          ($type == 'string' && $element instanceof StringInterface) ||
+          // Null values are allowed for all types.
+          ($value === NULL);
       }
+      $class = get_class($element);
       if (!$success) {
-        $class = get_class($element);
         $this->fail("{$this->configName}:$key has the wrong schema. Variable type is $type and schema class is $class.");
       }
     }
diff --git a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.ignore.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.ignore.yml
new file mode 100644
index 0000000..3b64ae9
--- /dev/null
+++ b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.ignore.yml
@@ -0,0 +1,9 @@
+label: 'Label string'
+irrelevant: 123
+indescribable:
+  abc: 789
+  def:
+   - 456
+   - 'abc'
+  xyz: 13.4
+weight: 27
diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
index 9eec7d7..34c6089 100644
--- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
+++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
@@ -132,3 +132,20 @@ config_schema_test.schema_in_install:
 config_schema_test_integer:
   type: integer
   label: 'Config test integer'
+
+config_schema_test.ignore:
+  type: mapping
+  label: 'Ignore test'
+  mapping:
+    label:
+      type: label
+      label: 'Label'
+    irrelevant:
+      type: ignore
+      label: 'Irrelevant'
+    indescribable:
+      type: ignore
+      label: 'Indescribable'
+    weight:
+      type: integer
+      label: 'Weight'
