diff --git a/epicardium/modules/meson.build b/epicardium/modules/meson.build
index 21a04ba5ec8464979127f1572b56a979ba34f08b..022397ca26e3866ef9a72472a7621e4cd6dbfec2 100644
--- a/epicardium/modules/meson.build
+++ b/epicardium/modules/meson.build
@@ -14,6 +14,7 @@ module_sources = files(
   'light_sensor.c',
   'log.c',
   'max30001.c',
+  'panic.c',
   'personal_state.c',
   'pmic.c',
   'rtc.c',
diff --git a/epicardium/modules/modules.h b/epicardium/modules/modules.h
index 465c78a4bda915927a10faafc90df911784f8574..bf59566b3e7ef168977ccf7606d55f445961da86 100644
--- a/epicardium/modules/modules.h
+++ b/epicardium/modules/modules.h
@@ -8,6 +8,10 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+/* ---------- Panic -------------------------------------------------------- */
+void panic(const char *format, ...)
+	__attribute__((noreturn, format(printf, 1, 2)));
+
 /* ---------- Dispatcher --------------------------------------------------- */
 void vApiDispatcher(void *pvParameters);
 void dispatcher_mutex_init(void);
diff --git a/epicardium/modules/panic.c b/epicardium/modules/panic.c
new file mode 100644
index 0000000000000000000000000000000000000000..e37f3d7a408eb40e5bbe4581339f1c38c53c6146
--- /dev/null
+++ b/epicardium/modules/panic.c
@@ -0,0 +1,63 @@
+/*
+ * Panic
+ * =====
+ *
+ * Under some conditions the firmware should crash and reboot automatically.
+ * This module provides the necessary facilities to do so.
+ *
+ * Note that a panic should indicate **only** logic-errors in the firmware or
+ * unrecoverable hardware conditions.
+ */
+
+#include "modules/log.h"
+#include "modules/modules.h"
+
+#include "card10.h"
+#include "card10-version.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+void __attribute__((noreturn)) panic(const char *format, ...)
+{
+	/* Turn off interrupts.  We won't get back from here anyway. */
+	__asm volatile("cpsid	i" ::: "memory");
+
+	/*
+	 * Turn off asynchronous printing because that won't ever work from
+	 * here ...
+	 */
+	serial_return_to_synchronous();
+
+	printf("\x1b[31;1m           --- SYSTEM PANIC ---\n"
+	       "\x1b[0;31m         ---                  ---\n"
+	       "       ---                      ---\n"
+	       "\x1b[0m A fatal error occured:\n     \x1b[1m");
+
+	va_list ap;
+	va_start(ap, format);
+	vprintf(format, ap);
+	va_end(ap);
+
+	printf("\n"
+	       "\x1b[0m\n"
+	       " Firmware Version:\n"
+	       "\x1b[35m     %s\n",
+	       CARD10_VERSION);
+
+	printf("\x1b[0m\n"
+	       " Stack Trace:\n"
+	       "\x1b[36m     %p\n",
+	       __builtin_return_address(0));
+
+	printf("\x1b[33m\n"
+	       " Please report this error to the card10 firmware team!\n"
+	       "\x1b[0m -> https://git.card10.badge.events.ccc.de/card10/firmware/issues/new?issue <-\n"
+	       "\x1b[31m           --- ====== ===== ---\x1b[0m\n");
+
+	for (int i = 0; i < 96000000; i++) {
+		__asm volatile("nop");
+	}
+
+	card10_reset();
+}