diff --git a/glnx-errors.h b/glnx-errors.h
index e26a513e39fa11f39153a2c519f13c6d41bf18eb..ecf7e85fc6681a5a08b220da8b5d1bf8bbedf232 100644
--- a/glnx-errors.h
+++ b/glnx-errors.h
@@ -84,6 +84,36 @@ glnx_prefix_error (GError **error, const char *fmt, ...)
 #define glnx_prefix_error_null(error, args...) \
   ({glnx_prefix_error (error, args); NULL;})
 
+/**
+ * GLNX_AUTO_PREFIX_ERROR:
+ *
+ * An autocleanup-based macro to automatically call `g_prefix_error()` (also with a colon+space `: `)
+ * when it goes out of scope.  This is useful when one wants error strings built up by the callee
+ * function, not all callers.
+ *
+ * ```
+ * gboolean start_http_request (..., GError **error)
+ * {
+ *   GLNX_AUTO_PREFIX_ERROR("HTTP request", error)
+ *
+ *   if (!libhttp_request_start (..., error))
+ *     return FALSE;
+ *   ...
+ *   return TRUE;
+ * ```
+ */
+typedef struct {
+  const char *prefix;
+  GError **error;
+} GLnxAutoErrorPrefix;
+static inline void
+glnx_cleanup_auto_prefix_error (GLnxAutoErrorPrefix *prefix)
+{
+  g_prefix_error (prefix->error, "%s: ", prefix->prefix);
+}
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxAutoErrorPrefix, glnx_cleanup_auto_prefix_error)
+#define GLNX_AUTO_PREFIX_ERROR(text, error) g_auto(GLnxAutoErrorPrefix) _GLNX_MAKE_ANONYMOUS(_glnxautoprefixerror_) = { text, error }
+
 /* Set @error using the value of `g_strerror (errno)`.
  *
  * This function returns %FALSE so it can be used conveniently in a single
diff --git a/tests/test-libglnx-errors.c b/tests/test-libglnx-errors.c
index 721818ba10341912b0ce704c743e07afa157023a..4e91e02c6e225ca8e95aaa068076de22185f4962 100644
--- a/tests/test-libglnx-errors.c
+++ b/tests/test-libglnx-errors.c
@@ -125,6 +125,48 @@ test_error_errno (void)
     g_assert_cmpint (fd, ==, -1);
 }
 
+static void
+test_error_auto_nothrow (GError **error)
+{
+  GLNX_AUTO_PREFIX_ERROR("foo", error);
+  /* Side effect to avoid otherwise empty function */
+  g_assert_no_error (*error);
+}
+
+static void
+test_error_auto_throw (GError **error)
+{
+  GLNX_AUTO_PREFIX_ERROR("foo", error);
+  (void) glnx_throw (error, "oops");
+}
+
+static void
+test_error_auto_throw_recurse (GError **error)
+{
+  GLNX_AUTO_PREFIX_ERROR("foo", error);
+
+  if (TRUE)
+    {
+      GLNX_AUTO_PREFIX_ERROR("bar", error);
+      (void) glnx_throw (error, "oops");
+    }
+}
+
+static void
+test_error_auto (void)
+{
+  g_autoptr(GError) error = NULL;
+  test_error_auto_nothrow (&error);
+  g_assert_no_error (error);
+  test_error_auto_throw (&error);
+  g_assert_nonnull (error);
+  g_assert_cmpstr (error->message, ==, "foo: oops");
+  g_clear_error (&error);
+  test_error_auto_throw_recurse (&error);
+  g_assert_nonnull (error);
+  g_assert_cmpstr (error->message, ==, "foo: bar: oops");
+}
+
 int main (int argc, char **argv)
 {
   int ret;
@@ -133,6 +175,7 @@ int main (int argc, char **argv)
 
   g_test_add_func ("/error-throw", test_error_throw);
   g_test_add_func ("/error-errno", test_error_errno);
+  g_test_add_func ("/error-auto", test_error_auto);
 
   ret = g_test_run();