diff --git a/gio/gsettings.c b/gio/gsettings.c
index 6ad842a..81c2ec2 100644
--- a/gio/gsettings.c
+++ b/gio/gsettings.c
@@ -27,8 +27,10 @@
 #include "gsettings.h"
 
 #include "gdelayedsettingsbackend.h"
+#include "ginitable.h"
 #include "gsettingsbackendinternal.h"
 #include "gsettings-mapping.h"
+#include "gioerror.h"
 #include "gio-marshal.h"
 #include "gsettingsschema.h"
 
@@ -179,8 +181,6 @@ enum
 
 static guint g_settings_signals[N_SIGNALS];
 
-G_DEFINE_TYPE (GSettings, g_settings, G_TYPE_OBJECT)
-
 static gboolean
 g_settings_real_change_event (GSettings    *settings,
                               const GQuark *keys,
@@ -341,13 +341,26 @@ settings_backend_path_writable_changed (GSettingsBackend *backend,
                    0, (GQuark) 0, &ignore_this);
 }
 
-static void
-g_settings_constructed (GObject *object)
+static gboolean
+g_settings_initable_init (GInitable    *initable,
+                          GCancellable *cancellable,
+                          GError      **error)
 {
-  GSettings *settings = G_SETTINGS (object);
+  GSettings *settings = G_SETTINGS (initable);
+  GSettingsPrivate *priv = settings->priv;
   const gchar *schema_path;
 
-  settings->priv->schema = g_settings_schema_new (settings->priv->schema_name);
+  if (cancellable != NULL)
+    {
+      g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+                           _("Cancellable initialization not supported"));
+      return FALSE;
+    }
+
+  priv->schema = g_settings_schema_new (settings->priv->schema_name, error);
+  if (priv->schema == NULL)
+    return FALSE;
+
   schema_path = g_settings_schema_get_path (settings->priv->schema);
 
   if (settings->priv->path && schema_path && strcmp (settings->priv->path, schema_path) != 0)
@@ -374,9 +387,21 @@ g_settings_constructed (GObject *object)
                             settings_backend_path_writable_changed);
   g_settings_backend_subscribe (settings->priv->backend,
                                 settings->priv->path);
+
+  return TRUE;
 }
 
 static void
+g_settings_initable_iface_init (GInitableIface *iface)
+{
+  iface->init = g_settings_initable_init;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GSettings, g_settings, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+                                                g_settings_initable_iface_init))
+
+static void
 g_settings_init (GSettings *settings)
 {
   settings->priv = G_TYPE_INSTANCE_GET_PRIVATE (settings,
@@ -545,12 +570,19 @@ static void
 g_settings_finalize (GObject *object)
 {
   GSettings *settings = G_SETTINGS (object);
+  GSettingsPrivate *priv = settings->priv;
+
+  if (priv->backend)
+    {
+      g_settings_backend_unsubscribe (priv->backend, priv->path);
+      g_object_unref (settings->priv->backend);
+    }
 
-  g_settings_backend_unsubscribe (settings->priv->backend,
-                                  settings->priv->path);
   g_main_context_unref (settings->priv->main_context);
-  g_object_unref (settings->priv->backend);
-  g_object_unref (settings->priv->schema);
+
+  if (priv->schema)
+    g_object_unref (priv->schema);
+
   g_free (settings->priv->schema_name);
   g_free (settings->priv->path);
 }
@@ -565,7 +597,6 @@ g_settings_class_init (GSettingsClass *class)
 
   object_class->set_property = g_settings_set_property;
   object_class->get_property = g_settings_get_property;
-  object_class->constructed = g_settings_constructed;
   object_class->finalize = g_settings_finalize;
 
   g_type_class_add_private (object_class, sizeof (GSettingsPrivate));
@@ -995,6 +1026,7 @@ g_settings_get_child (GSettings   *settings,
   gchar *child_path;
   gchar *child_name;
   GSettings *child;
+  GError *error = NULL;
 
   g_return_val_if_fail (G_IS_SETTINGS (settings), NULL);
 
@@ -1007,10 +1039,15 @@ g_settings_get_child (GSettings   *settings,
              settings->priv->schema_name, name);
 
   child_path = g_strconcat (settings->priv->path, child_name, NULL);
-  child = g_object_new (G_TYPE_SETTINGS,
-                        "schema", g_variant_get_string (child_schema, NULL),
-                        "path", child_path,
-                        NULL);
+  child = g_initable_new (G_TYPE_SETTINGS,
+                          NULL /* cancellable */,
+                          &error,
+                          "schema", g_variant_get_string (child_schema, NULL),
+                          "path", child_path,
+                          NULL);
+  if (child == NULL)
+    g_error ("Failed to create settings: %s", error->message);
+
   g_variant_unref (child_schema);
   g_free (child_path);
   g_free (child_name);
@@ -1035,15 +1072,25 @@ g_settings_get_child (GSettings   *settings,
 GSettings *
 g_settings_new (const gchar *schema)
 {
-  return g_object_new (G_TYPE_SETTINGS,
-                       "schema", schema,
-                       NULL);
+  GSettings *settings;
+  GError *error = NULL;
+
+  settings = g_initable_new (G_TYPE_SETTINGS,
+                             NULL /* cancellable */,
+                             &error,
+                             "schema", schema,
+                             NULL);
+  if (settings == NULL)
+    g_error ("Failed to create settings: %s", error->message);
+
+  return settings;
 }
 
 /**
  * g_settings_new_with_path:
  * @schema: the name of the schema
  * @path: the path to use
+ * @error: (allow-none): a location to store a #GError, or %NULL
  * @returns: a new #GSettings object
  *
  * Creates a new #GSettings object with a given schema and path.
@@ -1061,16 +1108,26 @@ GSettings *
 g_settings_new_with_path (const gchar *schema,
                           const gchar *path)
 {
-  return g_object_new (G_TYPE_SETTINGS,
-                       "schema", schema,
-                       "path", path,
-                       NULL);
+  GSettings *settings;
+  GError *error = NULL;
+
+  settings = g_initable_new (G_TYPE_SETTINGS,
+                             NULL /* cancellable */,
+                             &error,
+                             "schema", schema,
+                             "path", path,
+                             NULL);
+  if (settings == NULL)
+    g_error ("Failed to create settings: %s", error->message);
+
+  return settings;
 }
 
 /**
  * g_settings_new_with_context:
  * @schema: the name of the schema
  * @context: the context to use
+ * @error: (allow-none): a location to store a #GError, or %NULL
  * @returns: a new #GSettings object
  *
  * Creates a new #GSettings object with a given schema and context.
@@ -1091,10 +1148,19 @@ GSettings *
 g_settings_new_with_context (const gchar *schema,
                              const gchar *context)
 {
-  return g_object_new (G_TYPE_SETTINGS,
-                       "schema", schema,
-                       "context", context,
-                       NULL);
+  GSettings *settings;
+  GError *error = NULL;
+
+  settings = g_initable_new (G_TYPE_SETTINGS,
+                             NULL /* cancellable */,
+                             &error,
+                             "schema", schema,
+                             "context", context,
+                             NULL);
+  if (settings == NULL)
+    g_error ("Failed to create settings: %s", error->message);
+
+  return settings;
 }
 
 /**
@@ -1116,11 +1182,20 @@ g_settings_new_with_context_and_path (const gchar *schema,
                                       const gchar *context,
                                       const gchar *path)
 {
-  return g_object_new (G_TYPE_SETTINGS,
-                       "schema", schema,
-                        "context", context,
-                        "path", path,
-                        NULL);
+  GSettings *settings;
+  GError *error = NULL;
+
+  settings = g_initable_new (G_TYPE_SETTINGS,
+                             NULL /* cancellable */,
+                             &error,
+                             "schema", schema,
+                             "context", context,
+                             "path", path,
+                             NULL);
+  if (settings == NULL)
+    g_error ("Failed to create settings: %s", error->message);
+
+  return settings;
 }
 
 typedef struct
diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c
index af2c7d8..79a9cfa 100644
--- a/gio/gsettingsschema.c
+++ b/gio/gsettingsschema.c
@@ -129,7 +129,8 @@ g_settings_schema_get_string (GSettingsSchema *schema,
 }
 
 GSettingsSchema *
-g_settings_schema_new (const gchar *name)
+g_settings_schema_new (const gchar *name,
+                       GError     **error)
 {
   GSettingsSchema *schema;
   GvdbTable *table = NULL;
@@ -146,7 +147,11 @@ g_settings_schema_new (const gchar *name)
     }
 
   if (table == NULL)
-    g_error ("Settings schema '%s' is not installed\n", name);
+    {
+      g_set_error (error, 0, 0, /* FIXME use real error domain+code */
+                   "Settings schema '%s' is not installed\n", name);
+      return NULL;
+    }
 
   schema = g_object_new (G_TYPE_SETTINGS_SCHEMA, NULL);
   schema->priv->name = g_strdup (name);
diff --git a/gio/gsettingsschema.h b/gio/gsettingsschema.h
index f57b015..64c66f5 100644
--- a/gio/gsettingsschema.h
+++ b/gio/gsettingsschema.h
@@ -55,7 +55,8 @@ struct _GSettingsSchema
 G_GNUC_INTERNAL
 GType                   g_settings_schema_get_type                      (void);
 G_GNUC_INTERNAL
-GSettingsSchema *       g_settings_schema_new                           (const gchar      *name);
+GSettingsSchema *       g_settings_schema_new                           (const gchar      *name,
+                                                                         GError          **error);
 G_GNUC_INTERNAL
 const gchar *           g_settings_schema_get_path                      (GSettingsSchema  *schema);
 G_GNUC_INTERNAL
