Y2038 — die zweite Jahrtausend-Bombe (Update Juni 2026)

Am 19. Januar 2038, um 03:14:07 UTC, läuft der vorzeichenbehaftete 32-Bit-Unix-Timestamp über. Was wie ein Problem für übermorgen klingt, ist 2026 schon eines für heute: Verträge mit 30-jähriger Laufzeit, Datenbankschemata, die jetzt eingefroren werden, und IoT-Geräte, die nie wieder ein Firmware-Update sehen. Ich habe in den letzten zwölf Monaten in drei Codebases auf Y2038-Bugs gestoßen — keiner war im Linux-Kernel, alle in Application-Code. Was 2026 wirklich noch kaputt ist und was du diese Woche prüfen kannst.

Worum geht es überhaupt?

Der Unix-Timestamp zählt die Sekunden seit dem 1. Januar 1970, 00:00:00 UTC. In sehr vielen Systemen wird dieser Zähler in einem signed int32 gehalten — also einer 32-Bit-Ganzzahl mit Vorzeichen. Der maximale Wert dort ist 2 147 483 647. Genau so viele Sekunden nach der Unix-Epoche liegt der 19. Januar 2038, 03:14:07 UTC. In der Sekunde danach kippt das Vorzeichenbit, und der Wert wird negativ — Systeme interpretieren das als 13. Dezember 1901, 20:45:52 UTC.

Klingt esoterisch, ist es aber nicht. Jedes Tool, das mit Datum oder Zeit rechnet, ist potenziell betroffen: Banken-Software, die Restlaufzeiten berechnet. Logging-Systeme, die nach Timestamps sortieren. Geräte mit fest verlöteter Echtzeit-Uhr. Und vor allem: Datenbank-Spalten vom Typ INT (statt BIGINT), die irgendwo zwischen 2003 und 2018 angelegt wurden, weil damals niemand über 2038 nachgedacht hat.

Y2038 trägt im Internet diverse Namen: Epochalypse, Y2K38, Unix Millennium Bug. Die meisten dieser Namen wurden vergeben, bevor irgendjemand das Problem ernsthaft auditiert hat. Heute, zwölf Jahre vor dem Stichtag, ist das Bild gemischt: einige Schichten sind sauber, andere sind ein Minenfeld. Die spannende Frage ist nicht »läuft der Kernel über« — sondern »welche Schicht in meinem Stack hat noch int32?«.

Wie ich Y2038 das erste Mal wirklich kapiert habe

Ich war 2019 in einem Projekt für eine Schweizer Privatbank, das Hypothekarverträge verwaltete. Die Software berechnete für jeden Vertrag das Enddatum — Standardlaufzeit zwischen 10 und 25 Jahren. Im Februar 2019 rief ein Kollege aus dem Operations-Team an: ein Vertrag, den jemand mit 30 Jahren Laufzeit erfasst hatte, zeigte im Reporting plötzlich als End-Datum den 13. Dezember 1901. Die Datenbank-Spalte war ein INT, das Backend-Framework rechnete mit Millisekunden, und beim Überlauf wurde aus +2 147 483 647 ein -2 147 483 648.

Was mich damals überrascht hat: das Bug war nicht im Kernel, nicht im Datenbank-Server, nicht in der Programmiersprache. Es war in uns — wir hatten den Spaltentyp einfach falsch gewählt und die Default-Werte der Migration nie überdacht. Linux war 64-bit, MySQL hätte BIGINT nehmen können, die Sprache (Java) hatte long für Timestamps. Trotzdem ist es im Application-Layer übergelaufen, weil irgendwo eine Konvertierung auf 32-Bit-Sekunden stattfand. Das ist der Grund, warum »der Kernel ist 64-Bit, also bin ich safe« eine sehr gefährliche Annahme ist.

Seitdem habe ich denselben Patch in zwei weiteren Projekten gemacht — einmal in einem PHP-CMS, das Cookies mit Expiry-Datum gesetzt hatte, und einmal in einer Telematik-Anwendung für Flotten-Fahrzeuge. Beide Codebases hatten Hunderte von »(int) Casts« auf Sekunden, und in jedem einzelnen davon lauerte das Problem. Wenn dein Code 2026 noch existiert, lauert es bei dir auch.

Linux: was im Kernel 2026 wirklich los ist

Der Linux-Kernel hat seit Version 5.6 (Februar 2020) auch auf 32-Bit-Architekturen 64-Bit-Zeitwerte. Die System-Calls wurden in einer langen, zähen Aufräum-Aktion über zwei Jahre umgestellt — der Patch-Set heißt im Kernel-Slang »y2038 conversion« und betraf primär time_t, struct timespec, struct timeval und etwa 50 weitere syscalls. Auf 64-Bit-Architekturen war das Problem nie da: time_t ist dort seit den frühen 2000ern ein 64-Bit-Integer.

Das bedeutet: wenn du eine moderne Linux-Distribution (Ubuntu 22.04 LTS, Debian 12, RHEL 9, Alpine 3.18 oder neuer) auf einem 64-Bit-Prozessor laufen lässt, ist dein Kernel sauber. Auch macOS und alle iOS-Versionen seit iPhone 5s sind sauber. Windows in seinen 21st-Century-Versionen hat ein eigenes 64-Bit-Time-Format und ist nie betroffen gewesen. Die BSDs (FreeBSD, OpenBSD, NetBSD) haben ebenfalls 64-Bit-time.

Wo es eng wird: Embedded-Linux auf 32-Bit-ARM ohne CONFIG_64BIT_TIME, Router-Firmware aus dem Zeitraum 2008–2018, OpenWrt-Builds, die bei einer alten Kernelversion festhängen, und alles, was glibc < 2.32 nutzt. Wenn du einen Industrie-PC mit ARMv7 oder MIPS hast, der seit 2017 unverändert läuft, ist das Risiko hoch. Auf dem Raspberry Pi 1 (ohne 64-Bit-CPU) ist Y2038 immer noch ein offenes Problem, je nach Kernel-Variante und glibc-Version.

Datenbanken: hier wird es wirklich teuer

Die größte unentdeckte Y2038-Bombe liegt nicht im OS, sie liegt in Datenbankschemata. MySQL hat einen Datentyp TIMESTAMP, der intern als 32-Bit-Sekunden seit der Epoche gespeichert wird und exakt am 19. Januar 2038 überläuft. DATETIME dagegen reicht bis zum Jahr 9999. Wer in den letzten 20 Jahren irgendwo created_at TIMESTAMP geschrieben hat, hat einen Bug eingebaut, der erst nach seinem eigenen Rentenalter aufschlägt.

PostgreSQL ist sauber: TIMESTAMP WITHOUT TIME ZONE und TIMESTAMPTZ nutzen intern einen 64-Bit-Mikrosekunden-Wert seit dem 1. Januar 2000 und reichen bis 294276 AD. SQLite speichert Daten als Text oder Real und ist deshalb formell sauber, hat aber je nach Library-Wrapper das Problem trotzdem. Oracle nutzt ein eigenes Format und ist nicht betroffen. SQL Server ebenfalls nicht. Die schlimmste Falle ist heute MySQL/MariaDB TIMESTAMP — und der ist verdammt verbreitet.

Konkret: wenn du eine WordPress-, Magento-, Shopware-, Drupal- oder Joomla-Installation aus den letzten 15 Jahren hast, schau in dein Schema. wp_users.user_registered ist ein DATETIME (sauber), wp_posts.post_date_gmt ebenfalls. Aber jeder dritte Plugin-Autor hat sich für TIMESTAMP entschieden, weil es 4 Byte statt 8 spart. Für deine private Plugin-Tabelle bedeutet das: ALTER TABLE … MODIFY column DATETIME ist deine Hausaufgabe vor 2038. Besser jetzt — die Migration eines vollen MySQL-TIMESTAMP-Indexes auf einer 50-Millionen-Zeilen-Tabelle dauert nicht 5 Minuten.

PHP, Python, JavaScript: Stand 2026

PHP time() liefert seit jeher einen Integer — auf 64-Bit-Systemen also einen 64-Bit-Integer und damit sauber bis 292 Mrd. Jahre nach 1970. Aber: mktime(), strtotime() und DateTime auf 32-Bit-PHP (das es noch gibt!) sind betroffen. Wer einen Shared-Hoster nutzt, dessen PHP-Build aus pre-2018 ist, sollte einen Blick auf PHP_INT_SIZE werfen. Ist der Wert 4, hast du ein Problem. Ist er 8, ist die Sprache safe — die Schicht darüber aber vielleicht nicht.

Python's time.time() gibt einen Float zurück, was den Y2038-Bug formell ausschaltet — Doubles können viel größere Werte halten. Aber: struct.pack("i", timestamp) mit 'i' als 32-Bit-Signed-Int ist überall in alten Skripten, die mit Binär-Protokollen sprechen. SCADA-Protokolle, Modbus-Wrapper, alte Wago-PLC-Treiber — alles potenzielle Stolperstellen. Bei mir lag der letzte Treffer in einer 12 Jahre alten Python-Lib, die Schiffsdaten in NMEA-Format serialisierte.

JavaScript ist auf den ersten Blick safe: Date.now() liefert Millisekunden seit der Epoche als Number (also Double), und der maximale exakt darstellbare Integer ist 2^53. Praktisch kein Y2038-Problem im Sprachkern. Aber: jeder, der Timestamps als Math.floor(Date.now() / 1000) berechnet und in einem Int32Array oder mit DataView.setInt32() ablegt, baut das Problem manuell wieder ein. Und genau das tun WebSocket-Frames, Protobuf-Serialisierungen, IndexedDB-Schemata. Die Sprache ist sauber, der Anwendungs-Layer ist es nicht automatisch.

Embedded, IoT, Industrie: die echte Bombe

Hier wird Y2038 ein systemisches Problem, weil die Geräte länger laufen als die Update-Bereitschaft ihrer Hersteller. Eine Photovoltaik-Wechselrichter-Generation aus 2015 hat eine Lebensdauer von 20–25 Jahren. Eine SPS in einer Wasseraufbereitungsanlage läuft 30 Jahre ohne Anrühren. Ein Kassensystem in einer schweizerischen Bahnhofs-Pizzeria — ich habe 2024 eines gesehen, das seit 2008 nicht angefasst wurde. Wenn das Ding 2038 noch läuft (was wahrscheinlich ist), wird Y2038 dort live.

Konkrete Branchen mit erhöhtem Risiko: Industrie-Automatisierung (SPS, SCADA), Gebäude-Leittechnik (KNX, BACnet-Bridges), medizinische Geräte mit langer Zulassung (Beatmungsgeräte, MRT-Steuerungen), Auto-Steuergeräte aus dem Zeitraum 2010–2018, Avionik-Subsysteme, GPS-Tracker mit alten u-blox-Modulen. Die Hersteller-Reaktion ist überall die gleiche: Schweigen, bis 2035, dann Panik.

Mein realistisch-pessimistischer Blick: irgendwo zwischen 2035 und 2037 wird eine erste größere Y2038-Geschichte durch die Tech-Presse gehen — wahrscheinlich aus einem unerwarteten Sektor wie Smart-Meter oder elektronisches Türschloss. Die ersten Bug-Bounties werden geschrieben. Versicherer fangen an, Y2038-Audits zu verlangen. Wer 2035 mit 5 Jahren Migrations-Notwendigkeit dasteht, hat verloren. Wer 2026 ein Inventar macht, hat 12 Jahre Puffer. Genau jetzt ist eine sehr gute Zeit, das zu tun.

Code-Audit: was du diese Woche prüfen kannst

Konkrete Schritte, die in 30 Minuten machbar sind und überraschend viel zeigen:

  • Datenbank-Schemata greppen: SELECT * FROM information_schema.columns WHERE data_type = 'timestamp'; auf MySQL/MariaDB. Jede Zeile in der Antwort ist ein Kandidat für die Migration auf DATETIME.
  • Codebase auf (int)-Casts grep: in PHP grep -rn '(int)\s*\$\?[a-zA-Z_]*time' ., in JavaScript Suche nach | 0 und Math.floor kombiniert mit Date. Jeder Treffer ist verdächtig.
  • 32-Bit-Builds aufspüren: php -i | grep "Architecture", file $(which python3), uname -m. Wenn irgendwo i386, i686 oder armv7l auftaucht und das System weiterlaufen soll, planst du eine Migration auf 64-Bit.
  • Binär-Serialisierungen prüfen: Protokoll-Buffer (.proto-Dateien) auf int32-Felder mit »time« im Namen scannen. Avro/Thrift-Schemata auf i32-Timestamps prüfen. Diese Felder sind oft auf der Wire-Protocol-Ebene festgeschrieben und schwer zu migrieren.
  • Test mit Datum 19.01.2038: setze in einer Testumgebung das Systemdatum auf den 18. Januar 2038, lass deine Test-Suite laufen, schau zu, wie viel rot wird. Auf vielen Systemen brennt es schon vor dem eigentlichen Stichtag, weil Zeit-Differenzen über den Schwellenwert hinweg berechnet werden.

Wer einen Unix-Timestamp manuell prüfen will, kann mit unserem Unix-Timestamp-Converter jede beliebige Sekundenzahl in ein lesbares Datum übersetzen — inklusive der berühmten 2 147 483 647, die das Ende der 32-Bit-Ära markiert.

Y2038 ist nicht Y2K — und das ist das Problem

Y2K war ein zwei-Jahres-Sprint: Politik, Presse, Versicherer und IT-Abteilungen haben gemeinsam zwischen 1997 und 1999 in eine Lösung investiert, die geschätzt 300–600 Milliarden Dollar weltweit kostete. Hinterher wurde es als »nichts passiert« abgetan, weil dank der Vor-Arbeit tatsächlich nichts passiert ist. Die Pointe ist: ohne diese Vor-Arbeit wäre es ein Desaster gewesen.

Y2038 hat dieselbe systemische Tragweite, aber ohne die mediale Aufmerksamkeit. Es gibt keinen Y2038-Industrieverband, keinen YK38-Kongress-Hearing, keine Talkshow-Erklärbär-Folge. Das könnte ein blinder Fleck sein, der erst 2034 sichtbar wird. Wer jetzt anfängt, sitzt mit einer ruhigen Hand am Audit. Wer 2034 anfängt, sitzt mit einem Bug-Bounty-Programm da, das niemand mehr bezahlen will. Es lohnt sich, ein paar Stunden in ein Inventar zu investieren — selbst wenn du am Ende feststellst, dass alles sauber ist.

Was kommt bis 2038?

Eine realistische Roadmap, die ich für CalcSI und für ein paar Kunden so umsetze: 2025–2027 Inventar (welche Systeme, welche Schichten?), 2027–2030 Planung und Budgetierung, 2030–2036 Implementierung und Ausrollung, 2036–2038 Reservezeit für die typischen drei-vier-Probleme, die niemand auf dem Schirm hatte. Das ist großzügig — und nötig, weil Migrationen an realen Daten-Mengen einfach Zeit brauchen.

Das gute Nachricht 2026: die Toolchain ist ready. Glibc, Linux-Kernel, alle modernen Datenbank-Engines, alle Mainstream-Sprachen sind sauber. Das schlechte: niemand fühlt sich für die Anwendungs-Layer verantwortlich. Das ist genau der Punkt, wo ein einzelner Tag mit grep und einem Wochenende mit Schema-Migration einen jetzt riesigen Hebel hat. Tu's, solange es noch billig ist.

Häufige Fragen

Reicht es, alles auf 64-Bit-CPU umzuziehen?

Nein. Eine 64-Bit-CPU heißt nicht automatisch 64-Bit-Time. Java int bleibt 32-Bit, auch auf einer ARM64-CPU. Eine MySQL-TIMESTAMP-Spalte bleibt 32-Bit-Sekunden, auch wenn der Server auf x86_64 läuft. Eine .proto-Datei mit int32 bleibt 32-Bit auch nach einem Compiler-Update. Du musst die Anwendung anschauen, nicht die Hardware.

Was passiert um 03:14:07 UTC am 19.01.2038 in einem Linux-System mit veralteter Kernel-Version?

Der Kernel sieht eine negative time_t und ist verwirrt. uptime liefert komische Werte. Cron-Jobs feuern entweder nie mehr oder zu seltsamen Zeiten. Logs werden mit Datum 1901 geschrieben. SSL-Zertifikate werden als nicht-valide eingestuft, weil ihre notBefore-Zeit in der Zukunft liegt. Im schlimmsten Fall fällt der Boot-Prozess aus. Realistisch: ein degradiertes, halb funktionsfähiges System, das niemand reparieren kann, ohne Strom abschalten und Hardware-Uhr verstellen.

Wie teste ich mein System ohne in die Zukunft zu reisen?

Auf Linux: sudo timedatectl set-ntp false und dann sudo date -s "2038-01-18 23:00:00 UTC" in einer Test-VM. Achtung: TLS-Verbindungen brechen, das System sollte nicht ans Netz. Auf Docker geht es eleganter mit --env FAKETIME="2038-01-18 23:00:00" und der Library libfaketime — die fängt Zeit-Calls ab, ohne den Host zu beeinflussen. Letzteres ist mein Standard-Workflow für Y2038-Audits.

Gibt es einen Y2038 für Millisekunden-Timestamps?

Ja, aber mit anderem Datum. Ein 32-Bit-Signed-Integer für Millisekunden läuft schon am 19. Januar 1970, 19:14:07 UTC über — also seit 56 Jahren ein Bug, falls jemand das tatsächlich so implementieren würde. Ein 32-Bit-Unsigned-Integer für Sekunden reicht bis 2106. Ein 64-Bit-Integer für Millisekunden reicht bis 292 277 026 596. Praktisch: nutzt 64-Bit, fertig.

Mein WordPress läuft auf MySQL — bin ich betroffen?

Die Core-Tabellen von WordPress nutzen DATETIME und sind sauber. Pflichtcheck ist SHOW CREATE TABLE wp_users\G — wenn dort user_registered datetime steht, bist du auf der Core-Seite sicher. Plugin-Tabellen sind ein anderes Thema: SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS WHERE DATA_TYPE = 'timestamp' AND TABLE_SCHEMA = DATABASE(); zeigt dir alle 32-Bit-Fallen in deiner DB. Bei mir kamen da typischerweise WooCommerce-Logs, Backup-Plugins und ältere SEO-Tools heraus.

Soll ich jetzt sofort migrieren oder kann ich noch warten?

Inventar machen ist jetzt. Migration kannst du staffeln, aber nicht aufschieben. Eine MySQL-TIMESTAMP-Spalte auf 100 Mio Zeilen zu migrieren dauert je nach Hardware 2–6 Stunden Downtime — das wirst du nicht im Notfall-Modus machen wollen. Embedded-Updates auf gefälltem Hardware mit Firmware-Signing brauchen oft Jahre für die Roll-out-Logistik. Wer 2030 anfängt, hat noch viel Puffer. Wer 2035 anfängt, hat keinen. Die Zeit zwischen 2026 und 2030 ist der Sweet Spot.

Hinweis: Die Aussagen in diesem Artikel sind nach bestem Wissen und Gewissen recherchiert (Stand Juni 2026). Sie ersetzen keinen formalen Y2038-Audit für regulierte Systeme (Finanzen, Medizin, Avionik). Wer eine kritische Infrastruktur betreibt, sollte einen spezialisierten Auditor hinzuziehen.

Kommentare