diff --git a/Makefile b/Makefile
index e60eb4b..1c1ee86 100644
--- a/Makefile
+++ b/Makefile
@@ -125,7 +125,7 @@ obj-y += buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
 obj-y += qemu-char.o aio.o net-checksum.o savevm.o
 obj-y += msmouse.o ps2.o
 obj-y += qdev.o qdev-properties.o
-obj-y += qint.o qstring.o qdict.o qlist.o qmisc.o qemu-config.o
+obj-y += qint.o qstring.o qdict.o qlist.o qmisc.o qerror.o qemu-config.o
 
 obj-$(CONFIG_BRLAPI) += baum.o
 obj-$(CONFIG_WIN32) += tap-win32.o
diff --git a/qerror.c b/qerror.c
new file mode 100644
index 0000000..bbea770
--- /dev/null
+++ b/qerror.c
@@ -0,0 +1,189 @@
+/*
+ * QError: QEMU Error data-type.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+#include "sysemu.h"
+#include "qint.h"
+#include "qmisc.h"
+#include "qlist.h"
+#include "qerror.h"
+#include "qstring.h"
+#include "qemu-common.h"
+
+static void qerror_destroy_obj(QObject *obj);
+
+static const QType qerror_type = {
+    .code = QTYPE_QERROR,
+    .destroy = qerror_destroy_obj,
+};
+
+static QErrorTable qerror_table[] = {
+    {
+        .code   = QERR_UNKNOWN,
+        .desc   = "unknown error",
+    },
+};
+
+/**
+ * qerror_new(): Create a new QError
+ *
+ * Return strong reference.
+ */
+QError *qerror_new(void)
+{
+    QError *qerr;
+
+    qerr = qemu_mallocz(sizeof(*qerr));
+    QOBJECT_INIT(qerr, &qerror_type);
+
+    return qerr;
+}
+
+/*
+ * qerror_from_va(): Create a new QError from a va_list
+ *
+ * The specified format and va_list are used to build the specific
+ * error data object, which is stored in the 'data' member of QError.
+ *
+ * Return strong reference.
+ */
+QError *qerror_from_va(QErrorCode code, const char *fmt, va_list va)
+{
+    QError *qerr;
+
+    assert((code > 0) && (code < QERR_MAX));
+
+    qerr = qerror_new();
+    qerr->entry = &qerror_table[code];
+    if (fmt) {
+        qerr->data = qobject_from_va(fmt, va);
+        if (!qerr->data) {
+            qemu_free(qerr);
+            return NULL;
+        }
+    }
+
+    return qerr;
+}
+
+static int show_dict_sep;
+static int show_list_sep;
+static void qerror_qobject_print(const QObject *obj);
+
+static void print_qdict(const char *key, QObject *obj, void *opaque)
+{
+    if (show_dict_sep)
+        qemu_error(",");
+
+    qemu_error("%s=", key);
+    qerror_qobject_print(obj);
+
+    show_dict_sep = 1;
+}
+
+static void print_qlist(QObject *obj, void *opaque)
+{
+    if (show_list_sep)
+        qemu_error(",");
+
+    qerror_qobject_print(obj);
+
+    show_list_sep = 1;
+}
+
+static void qerror_qobject_print(const QObject *obj)
+{
+    if (!obj)
+        return;
+
+    switch (qobject_type(obj)) {
+        case QTYPE_QINT:
+            qemu_error("%" PRId64, qint_get_int(qobject_to_qint(obj)));
+            break;
+        case QTYPE_QSTRING:
+            qemu_error("%s", qstring_get_str(qobject_to_qstring(obj)));
+            break;
+        case QTYPE_QDICT:
+            show_dict_sep = 0;
+            qdict_iter(qobject_to_qdict(obj), print_qdict, NULL);
+            break;
+        case QTYPE_QLIST:
+            show_list_sep = 0;
+            qlist_iter(qobject_to_qlist(obj), print_qlist, NULL);
+            break;
+        default:
+            abort();
+            break;
+    }
+}
+
+/**
+ * qerror_default_print(): Standard function to print QError data
+ */
+static void qerror_default_print(const QError *qerror)
+{
+    const QErrorTable *entry = qerror->entry;
+
+    if (entry->prefix)
+        qemu_error("%s: ", entry->prefix);
+
+    qemu_error("%s", entry->desc);
+    if (qerror->data) {
+        qemu_error(": ");
+        qerror_qobject_print(qerror->data);
+    }
+
+    qemu_error("\n");
+}
+
+/**
+ * qerror_print(): Print QError data
+ *
+ * This function calls the user_print() callback associated
+ * with the error to print QError data in human readable
+ * format.
+ *
+ * If the error does not define a user_print() callback, the
+ * standard one will be called.
+ */
+void qerror_print(const QError *qerror)
+{
+    if (qerror->entry->user_print) {
+        qerror->entry->user_print(qerror);
+    } else {
+        qerror_default_print(qerror);
+    }
+}
+
+/**
+ * qobject_to_qerror(): Convert a QObject into a QError
+ */
+QError *qobject_to_qerror(const QObject *obj)
+{
+    if (qobject_type(obj) != QTYPE_QERROR) {
+        return NULL;
+    }
+
+    return container_of(obj, QError, base);
+}
+
+/**
+ * qerror_destroy_obj(): Free all memory allocated by a QError
+ */
+static void qerror_destroy_obj(QObject *obj)
+{
+    QError *qerr;
+
+    assert(obj != NULL);
+    qerr = qobject_to_qerror(obj);
+
+    qobject_decref(qerr->data);
+    qemu_free(qerr);
+}
diff --git a/qerror.h b/qerror.h
new file mode 100644
index 0000000..ed25ef1
--- /dev/null
+++ b/qerror.h
@@ -0,0 +1,47 @@
+/*
+ * QError header file.
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ *
+ * Authors:
+ *  Luiz Capitulino <lcapitulino@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef QERROR_H
+#define QERROR_H
+
+#include <stdarg.h>
+#include "qobject.h"
+
+/*
+ * IMPORTANT: errors numbers must not change after they have been
+ * added here.
+ */
+typedef enum QErrorCode {
+    QERR_UNKNOWN,
+    QERR_MAX,
+} QErrorCode;
+
+struct QError;
+
+typedef struct QErrorTable {
+    QErrorCode code;
+    const char *prefix;
+    const char *desc;
+    void (*user_print)(const struct QError *qerror);
+} QErrorTable;
+
+typedef struct QError {
+    QObject_HEAD;
+    QObject *data; /* error specific data */
+    const QErrorTable *entry;
+} QError;
+
+QError *qerror_new(void);
+QError *qerror_from_va(QErrorCode code, const char *fmt, va_list va);
+QError *qobject_to_qerror(const QObject *obj);
+void qerror_print(const QError *qerror);
+
+#endif /* QERROR_H */
diff --git a/qobject.h b/qobject.h
index 4cc9287..484d4dd 100644
--- a/qobject.h
+++ b/qobject.h
@@ -41,6 +41,7 @@ typedef enum {
     QTYPE_QSTRING,
     QTYPE_QDICT,
     QTYPE_QLIST,
+    QTYPE_QERROR,
 } qtype_code;
 
 struct QObject;
