diff --git a/error.c b/error.c
index 1f05fc4..3f76fd5 100644
--- a/error.c
+++ b/error.c
@@ -21,12 +21,13 @@ struct Error
 {
     char *msg;
     ErrorClass err_class;
+    bool is_critical;
 };
 
-void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
+static void do_error_set(Error **errp, ErrorClass err_class,
+                         const char *fmt, va_list ap)
 {
     Error *err;
-    va_list ap;
 
     if (errp == NULL) {
         return;
@@ -35,14 +36,38 @@ void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
 
     err = g_malloc0(sizeof(*err));
 
-    va_start(ap, fmt);
     err->msg = g_strdup_vprintf(fmt, ap);
-    va_end(ap);
     err->err_class = err_class;
 
     *errp = err;
 }
 
+void error_set(Error **errp, ErrorClass err_class, const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    do_error_set(errp, err_class, fmt, ap);
+    va_end(ap);
+}
+
+void error_set_critical(Error **errp, ErrorClass err_class,
+                        const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    if (!errp) {
+        /* Critical error which would be ignored: print and abort now */
+        vfprintf(stderr, fmt, ap);
+        fputc('\n', stderr);
+        abort();
+    }
+
+    do_error_set(errp, err_class, fmt, ap);
+    (*errp)->is_critical = true;
+
+    va_end(ap);
+}
+
 Error *error_copy(const Error *err)
 {
     Error *err_new;
@@ -50,6 +75,7 @@ Error *error_copy(const Error *err)
     err_new = g_malloc0(sizeof(*err));
     err_new->msg = g_strdup(err->msg);
     err_new->err_class = err->err_class;
+    err_new->is_critical = err->is_critical;
 
     return err_new;
 }
@@ -82,6 +108,10 @@ void error_propagate(Error **dst_err, Error *local_err)
     if (dst_err && !*dst_err) {
         *dst_err = local_err;
     } else if (local_err) {
+        if (local_err->is_critical) {
+            fprintf(stderr, "%s\n", error_get_pretty(local_err));
+            abort();
+        }
         error_free(local_err);
     }
 }
diff --git a/error.h b/error.h
index da7fed3..4be0893 100644
--- a/error.h
+++ b/error.h
@@ -36,6 +36,18 @@ void error_set(Error **err, ErrorClass err_class, const char *fmt, ...) GCC_FMT_
     error_set(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
 
 /**
+ * Same as error_set(), but mark the error as critical
+ */
+void error_set_critical(Error **err, ErrorClass err_class,
+                        const char *fmt, ...) GCC_FMT_ATTR(3, 4);
+
+/**
+ * Same as error_setg(), but mark the error as critical
+ */
+#define error_setg_critical(err, fmt, ...) \
+    error_set_critical(err, ERROR_CLASS_GENERIC_ERROR, fmt, ## __VA_ARGS__)
+
+/**
  * Returns true if an indirect pointer to an error is pointing to a valid
  * error object.
  */
