Kurzfassung

Vier Nächte hintereinander meldete mir eine meiner Maschinen ein erfolgreiches Backup: Erfolgsmail, Kennzahlen an die Überwachung, Eintrag im Sicherungskatalog. Tatsächlich wurde in diesen vier Nächten kein einziges Byte gesichert. Der Fehler lag nicht im Sicherungswerkzeug und nicht im Speicherort, sondern in einer Umgebungsvariablen — und in einem Skript, das den Rückgabewert seines wichtigsten Befehls nie geprüft hat.

Der unangenehmste Satz in der Datensicherung lautet nicht „das Backup ist fehlgeschlagen". Eine Fehlermeldung ist ein Geschenk: Sie kommt sofort, sie ist eindeutig, man kann handeln. Der unangenehmste Satz lautet „das Backup war erfolgreich" — wenn er nicht stimmt.

Genau das ist mir passiert. Vier Nächte lang.

Die Meldung, der ich vier Nächte geglaubt habe

Auf einer meiner Maschinen läuft die nächtliche Sicherung als zeitgesteuerter Auftrag. Das Skript sichert die Daten, meldet das Ergebnis per Mail, schreibt Kennzahlen für die Überwachung und trägt den Lauf in einen zentralen Katalog ein, der über alle Maschinen hinweg festhält, wann zuletzt was gesichert wurde. Drei unabhängige Kanäle also.

Alle drei meldeten Erfolg. Der Katalog führte die Maschine als aktuell gesichert. Es gab keinen Alarm, keine Warnung, keinen roten Punkt in irgendeiner Übersicht.

Aufgefallen ist es mir bei einer turnusmäßigen Durchsicht — und zwar an einer einzigen Zahl in der Erfolgsmeldung:

FERTIG — Dauer: 0s

Null Sekunden. Eine Sicherung, die tatsächlich läuft, braucht auf dieser Maschine rund eine halbe Minute. Ein vollständiger Durchlauf mit mehreren Gigabyte dauert Minuten. Null Sekunden bedeutet: Es ist nichts passiert.

Warum niemand die Null bemerkt hat

Weil sie in einer Erfolgsmeldung stand. Wer eine Mail mit dem Betreff „Backup erfolgreich" öffnet, liest die Laufzeit nicht mit der Frage, ob sie plausibel ist. Man überfliegt sie und hakt sie ab. Genau darin liegt die Tücke: Ein stiller Ausfall ist gefährlicher als ein lauter, weil er die Kontrollmechanismen nicht auslöst, sondern bedient.

Im Log stand die Wahrheit unmittelbar daneben:

restic: command not found
BACKUP FEHLGESCHLAGEN: Rückgabewert 127

Rückgabewert 127 ist eine der eindeutigsten Meldungen, die eine Shell kennt: Kommando nicht gefunden. Nicht „fehlgeschlagen", nicht „teilweise", nicht „abgebrochen". Das Programm wurde nie gestartet. Es gab keinen Teilstand, keine unvollständige Sicherung — es gab nichts.

Das Skript hatte diesen Rückgabewert protokolliert und anschließend trotzdem Erfolg gemeldet. Es prüfte, ob es selbst bis zum Ende durchgelaufen war, nicht ob sein Hauptbefehl funktioniert hatte.

Die Ursache steht in keiner Handbuchseite

Das Sicherungsprogramm lag, wie üblich bei manuell installierten Werkzeugen, unter /usr/local/bin. Von Hand aufgerufen funktionierte es tadellos. Über den Zeitplaner nicht.

Der Grund ist der Suchpfad. Zeitgesteuerte Aufträge erben nicht die Umgebung einer Anmeldesitzung — sie starten mit einer bewusst minimalen. Auf dem betroffenen System umfasste der Suchpfad im Zeitplaner genau zwei Verzeichnisse: /usr/bin und /bin. In einer normalen Sitzung sind es ein Dutzend, darunter /usr/local/bin.

Das Bemerkenswerte daran: Die Handbuchseite des Zeitplaners dokumentiert diesen Standardwert nicht. Sie beschreibt präzise, dass die Shell auf /bin/sh gesetzt wird und dass Benutzername und Heimatverzeichnis aus der Benutzerdatenbank stammen.[1] Zum Suchpfad — der Variablen, an der in der Praxis die meisten Aufträge scheitern — steht dort nichts. Man erfährt den Wert nur, indem man ihn misst.

Dazu kam ein Umstand, der die Sache lange verdeckt hatte: Auf meinen übrigen Maschinen existiert zusätzlich eine Verknüpfung des Programms in /usr/bin. Dort funktionierte der nächtliche Lauf deshalb einwandfrei. Nur auf dieser einen fehlte sie. Eine Abweichung in der Grundausstattung, die nur unter der verkürzten Umgebung sichtbar wird — und sonst nie.

Der Reparaturversuch, der keiner war

Das ist der Teil, den ich am lehrreichsten finde.

Einen Tag zuvor hatte ich bereits einen Fehler an derselben Sicherung behoben — ein fehlendes Hilfsprogramm. Danach startete ich das Skript von Hand. Es lief sauber durch, legte einen echten Sicherungspunkt von knapp sieben Gigabyte an und brauchte dafür knapp drei Minuten. Für mich war die Sache damit erledigt.

Sie war es nicht. Der zeitgesteuerte Lauf am Abend desselben Tages scheiterte weiter — jetzt an der fehlenden Verknüpfung. Mein Testlauf hatte nichts bewiesen, weil er in meiner Sitzung lief, mit meinem vollständigen Suchpfad. Ich hatte geprüft, ob das Skript funktioniert, wenn ich es starte. Die Frage war aber, ob es funktioniert, wenn niemand es startet.

Das ist keine Nachlässigkeit im Einzelfall, sondern ein systematischer blinder Fleck: Die Umgebung, in der wir testen, ist fast nie die Umgebung, in der es später läuft.

Wie man es richtig prüft

Die Lösung ist unspektakulär: Man testet nicht mit seiner Umgebung, sondern ohne. Statt das Skript einfach aufzurufen, entfernt man zuerst sämtliche Umgebungsvariablen und setzt nur den knappen Suchpfad, den auch der Zeitplaner verwendet. Dann läuft der Test unter genau den Bedingungen, unter denen es nachts ernst wird.

Bei mir schlug das Skript in diesem Aufbau sofort fehl — mit derselben Meldung wie in den vier Nächten zuvor. Damit war die Ursache bestätigt, bevor ich irgendetwas repariert hatte. Nach dem Anlegen der fehlenden Verknüpfung lief derselbe Test durch und legte einen echten Sicherungspunkt in 25 Sekunden an. Erst diese zweite Messung war ein Beleg.

Was ich daraus geändert habe

Erfolg wird an der Sicherung festgemacht, nicht am Skript. Eine Erfolgsmeldung darf erst rausgehen, wenn ein neuer Sicherungspunkt tatsächlich existiert. Das ist eine Abfrage mehr — und der Unterschied zwischen „das Skript ist durchgelaufen" und „die Daten sind gesichert".

Unplausible Laufzeiten sind ein Alarm, kein Detail. Null Sekunden, oder ein Bruchteil des üblichen Werts, bedeutet fast immer, dass der eigentliche Vorgang übersprungen wurde. Diese Zahl gehört überwacht, nicht nur protokolliert.

Absolute Pfade in zeitgesteuerten Skripten. Wer den vollständigen Pfad zum Programm hinschreibt, ist vom Suchpfad unabhängig. Das ist die einzige Variante, die nicht davon abhängt, wie eine Maschine eingerichtet wurde.

Und die unbequemste Lehre: Ein Fix gilt erst als erledigt, wenn er unter den echten Bedingungen bewiesen wurde. Vier Nächte Datenverlust-Risiko entstanden nicht durch den ursprünglichen Fehler, sondern durch einen Test, der die falsche Frage beantwortet hat.

Das Sicherungswerkzeug selbst trifft übrigens keine Schuld. Seine Dokumentation weist ausdrücklich darauf hin, dass es keine eigene Zeitsteuerung mitbringt und auf externe Planer angewiesen ist.[2] Genau an dieser Nahtstelle — zwischen einem Werkzeug, das nur auf Zuruf läuft, und einem Planer mit minimaler Umgebung — entstehen diese Ausfälle.

Wie sich daraus eine tragfähige Sicherungsstrategie bauen lässt und warum nächtliche Sicherungen ohnehin weniger schützen, als man denkt, steht in Teil 1 dieser Serie. Was beim Zurückholen einzelner Dateien tatsächlich zählt, zeigt Teil 2.

Quellenverzeichnis

  • [1] crontab(5), Linux man-pages — abgerufen 15.08.2026. Dokumentiert, dass SHELL auf /bin/sh gesetzt und LOGNAME/HOME aus der Benutzerdatenbank übernommen werden. Ein Standardwert für PATH wird dort nicht angegeben — der im Text genannte Wert stammt aus eigener Messung auf dem betroffenen System und kann je nach Distribution und cron-Variante abweichen.
  • [2] restic-Dokumentation, Kapitel „Backing up" — abgerufen 15.08.2026 (Zitat: „Restic does not have a built-in way of scheduling backups, as it's a tool that runs when executed rather than a daemon.").
  • [3] Rückgabewert 127 als Kennzeichen für ein nicht gefundenes Kommando: eigene Messung, reproduzierbar in bash und sh (Aufruf eines nicht existierenden Kommandos, Prüfung des Rückgabewerts), 16.08.2026.
  • [4] Laufzeiten, Rückgabewerte und Sicherungsgrößen stammen aus den eigenen Wartungsprotokollen vom 12. bis 16.08.2026.

Transparenz: Der geschilderte Vorfall stammt aus dem Betrieb meiner eigenen Server im August 2026. Maschinennamen, Adressen und Zugangsdaten sind bewusst nicht genannt. Es besteht keine Geschäftsbeziehung zu den Anbietern der erwähnten Werkzeuge; die Infrastruktur ist vollständig selbst finanziert.

Hinweis zur Entstehung: Dieser Artikel wurde mit KI-Unterstützung durch Claude recherchiert und geschrieben. Die technischen Angaben wurden gegen Primärquellen und eigene Messungen geprüft; die redaktionelle Verantwortung liegt bei Marco Fuhrmann.

Angaben ohne Gewähr. Das beschriebene Verhalten des Zeitplaners kann je nach Distribution abweichen — im Zweifel auf dem eigenen System nachmessen.