diff --git a/ibis/ibismessage.h b/ibis/ibismessage.h
--- a/ibis/ibismessage.h
+++ b/ibis/ibismessage.h
@@ -191,6 +191,47 @@
 IBIS_AVAILABLE_IN_0_1
 char *ibis_message_serialize_to_string(IbisMessage *message);
 
+/**
+ * ibis_message_get_error:
+ * @message: The instance.
+ *
+ * Gets the error for @message.
+ *
+ * Errors are typically set on messages when they are being parsed and
+ * something isn't right.
+ *
+ * Returns: (transfer none) (nullable): The error if one is set, otherwise
+ *          %NULL.
+ *
+ * Since: 0.1
+ */
+IBIS_AVAILABLE_IN_0_1
+GError *ibis_message_get_error(IbisMessage *message);
+
+/**
+ * ibis_message_set_error:
+ * @message: The instance.
+ * @error: (nullable) (transfer none): The new error message.
+ *
+ * Sets the error for @message to @error.
+ *
+ * Since: 0.1
+ */
+IBIS_AVAILABLE_IN_0_1
+void ibis_message_set_error(IbisMessage *message, GError *error);
+
+/**
+ * ibis_message_take_error:
+ * @message: The instance.
+ * @error: (nullable) (transfer full): The new error message.
+ *
+ * Sets the error for @message to @error taking ownership of @error.
+ *
+ * Since: 0.1
+ */
+IBIS_AVAILABLE_IN_0_1
+void ibis_message_take_error(IbisMessage *message, GError *error);
+
 G_END_DECLS
 
 #endif /* IBIS_MESSAGE_H */
# HG changeset patch
# Node ID c1858b790617
# Parent  3f59c33c864e
diff --git a/ibis/ibismessage.c b/ibis/ibismessage.c
--- a/ibis/ibismessage.c
+++ b/ibis/ibismessage.c
@@ -32,6 +32,7 @@
 	PROP_SOURCE,
 	PROP_PARAMS,
 	PROP_TAGS,
+	PROP_ERROR,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -43,6 +44,7 @@
 	GStrv params;
 	char *source;
 	IbisTags *tags;
+	GError *error;
 };
 
 /******************************************************************************
@@ -152,6 +154,7 @@
 	g_clear_pointer(&message->params, g_strfreev);
 	g_clear_pointer(&message->source, g_free);
 	g_clear_object(&message->tags);
+	g_clear_error(&message->error);
 
 	G_OBJECT_CLASS(ibis_message_parent_class)->finalize(obj);
 }
@@ -175,6 +178,9 @@
 	case PROP_TAGS:
 		g_value_set_object(value, ibis_message_get_tags(message));
 		break;
+	case PROP_ERROR:
+		g_value_set_boxed(value, ibis_message_get_error(message));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -200,6 +206,9 @@
 	case PROP_TAGS:
 		ibis_message_set_tags(message, g_value_get_object(value));
 		break;
+	case PROP_ERROR:
+		ibis_message_set_error(message, g_value_get_boxed(value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -278,6 +287,19 @@
 		IBIS_TYPE_TAGS,
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
+	/**
+	 * IbisMessage:error:
+	 *
+	 * An error that was encountered when processing the message.
+	 *
+	 * Since: 0.1
+	 */
+	properties[PROP_ERROR] = g_param_spec_boxed(
+		"error", "error",
+		"An error that was encountered when processing the message.",
+		G_TYPE_ERROR,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
 	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
 }
 
@@ -392,3 +414,32 @@
 
 	return g_string_free_and_steal(ibis_message_serialize_internal(message));
 }
+
+GError *
+ibis_message_get_error(IbisMessage *message) {
+	g_return_val_if_fail(IBIS_IS_MESSAGE(message), NULL);
+
+	return message->error;
+}
+
+void
+ibis_message_set_error(IbisMessage *message, GError *error) {
+	g_return_if_fail(IBIS_IS_MESSAGE(message));
+
+	g_clear_error(&message->error);
+	if(error != NULL) {
+		message->error = g_error_copy(error);
+	}
+
+	g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]);
+}
+
+void
+ibis_message_take_error(IbisMessage *message, GError *error) {
+	g_return_if_fail(IBIS_IS_MESSAGE(message));
+
+	g_clear_error(&message->error);
+	message->error = error;
+
+	g_object_notify_by_pspec(G_OBJECT(message), properties[PROP_ERROR]);
+}
diff --git a/ibis/tests/test_message.c b/ibis/tests/test_message.c
--- a/ibis/tests/test_message.c
+++ b/ibis/tests/test_message.c
@@ -41,6 +41,8 @@
 	IbisMessage *message = NULL;
 	IbisTags *tags1 = NULL;
 	IbisTags *tags2 = NULL;
+	GError *error1 = NULL;
+	GError *error2 = NULL;
 	GStrv params1 = NULL;
 	GStrv params2 = NULL;
 	GStrvBuilder *builder = NULL;
@@ -56,12 +58,15 @@
 	params1 = g_strv_builder_end(builder);
 	g_strv_builder_unref(builder);
 
+	error1 = g_error_new(TEST_IBIS_MESSAGE_ERROR, 0, "weeeee");
+
 	message = g_object_new(
 		IBIS_TYPE_MESSAGE,
 		"command", "command",
 		"params", params1,
 		"source", "source",
 		"tags", tags1,
+		"error", error1,
 		NULL);
 
 	g_assert_true(IBIS_IS_MESSAGE(message));
@@ -72,6 +77,7 @@
 		"params", &params2,
 		"source", &source,
 		"tags", &tags2,
+		"error", &error2,
 		NULL);
 
 	g_assert_cmpstr(command, ==, "command");
@@ -87,8 +93,29 @@
 	g_assert_true(ibis_tags_equal(tags1, tags2));
 	g_clear_object(&tags2);
 
+	g_assert_error(error2, TEST_IBIS_MESSAGE_ERROR, 0);
+	g_clear_error(&error2);
+
 	g_clear_pointer(&params1, g_strfreev);
 	g_clear_object(&tags1);
+	g_clear_error(&error1);
+	g_assert_finalize_object(message);
+}
+
+static void
+test_ibis_message_take_error(void) {
+	IbisMessage *message = NULL;
+	GError *error1 = NULL;
+	GError *error2 = NULL;
+
+	message = ibis_message_new("PRIVMSG");
+
+	error1 = g_error_new(TEST_IBIS_MESSAGE_ERROR, 0, "weeeee");
+	ibis_message_take_error(message, error1);
+
+	error2 = ibis_message_get_error(message);
+	g_assert_error(error2, TEST_IBIS_MESSAGE_ERROR, 0);
+
 	g_assert_finalize_object(message);
 }
 
@@ -563,8 +590,8 @@
 	g_test_init(&argc, &argv, NULL);
 
 	g_test_add_func("/ibis/message/new", test_ibis_message_new);
-
 	g_test_add_func("/ibis/message/properties", test_ibis_message_properties);
+	g_test_add_func("/ibis/message/take-error", test_ibis_message_take_error);
 
 	g_test_add_func("/ibis/message/set-params-variadic",
 	                test_ibis_message_set_params_variadic);
