Error of the Day · Developers

The Year 2038 problem: when 32 bits of seconds run out

Y2K was about two-digit years. Y2038 is about a counter that runs out of room. Most laptops are already safe; the risk sits in database columns, file formats and devices nobody plans to replace.

WrongY2038 was fixed when everyone moved to 64-bit machines.

Right64-bit kernels and libraries are mostly fixed, but any 32-bit timestamp, whether in a database column, file format, protocol or embedded device, still overflows on January 19, 2038.

Memory trick 2^31 - 1 seconds after 1970 is 2038-01-19 03:14:07 UTC; check where your timestamps are stored, not just the CPU.

What people get wrong#

Unix-like systems keep time as a count of seconds since the Epoch, midnight UTC on January 1, 1970. POSIX defines this as "Seconds Since the Epoch". For decades that count lived in a time_t that was a signed 32-bit integer. The biggest value it can hold is 2^31 − 1, or 2,147,483,647.

That many seconds after the Epoch is 03:14:07 UTC on Tuesday, January 19, 2038. One second later the counter overflows and wraps to its most negative value, which a naive system reads as December 13, 1901.

>>> datetime.fromtimestamp(2**31 - 1, timezone.utc)
2038-01-19 03:14:07+00:00
>>> datetime.fromtimestamp(-2**31, timezone.utc)
1901-12-13 20:45:52+00:00

The common mistake is thinking this was settled when desktops went 64-bit. The CPU was never the issue. The issue is wherever a timestamp gets stored in 32 bits.

Where it still bites#

Database columns. MySQL's TIMESTAMP type has a documented range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC; DATETIME runs to the year 9999. A schema designed today with a TIMESTAMP "expires_at" column already can't hold a 15-year expiry date.

Language runtimes on 32-bit platforms. Python's docs warn that the future cut-off for its time functions "is determined by the C library; for 32-bit systems, it is typically in 2038". On such platforms localtime() can raise OverflowError.

Embedded and long-lived hardware. Routers, industrial controllers, cars and medical devices often run 32-bit chips for decades. LWN notes these might prove harder to fix as the date approaches, and argues they should be made 2038-ready when they're deployed.

Formats and protocols. Any binary file header, network message or serialized struct with a 32-bit seconds field has the same limit, whatever machine reads it.

Dates in the future, today. The bug doesn't wait for 2038. Anything that calculates a date 12 or more years out, such as a mortgage schedule, a certificate expiry or a "never expires" sentinel value, can overflow now.

What's been fixed#

A lot. Linux 5.6 (2020) was the first mainline kernel that 32-bit systems could use to run past 2038, provided user space is also built with a 64-bit time_t. By 2023, LWN described the kernel as "mostly free of year-2038 problems," with glibc able to handle 32-bit or 64-bit time_t depending on how a program is compiled. The remaining work is in distributions, libraries and applications. That's harder, because changing the size of time_t breaks binary compatibility.

The fix#

CREATE TABLE tokens (expires_at TIMESTAMP);

CREATE TABLE tokens (expires_at DATETIME); -- or a 64-bit integer of epoch seconds

Store time in types that reach past 2038, then test with dates that do.

  • Use 64-bit time everywhere you store or send it. Integers of epoch seconds or milliseconds should be int64, not int32.
  • Grep for the risky types: int32 or uint32 timestamp fields, MySQL TIMESTAMP columns, and C structs packed for file formats.
  • When building C code for 32-bit targets, compile against a C library with 64-bit time_t support, and rebuild dependencies the same way.
  • Test with the future. Fake the clock to 2038-01-19 03:14:08 UTC and to 2040 in your integration tests. Bugs that only appear on a date are easy to miss in review and easy to catch in a test.

Twelve years sounds like plenty of time. Y2K once looked far away too.

Sources

Every factual claim on this page links to one of these. Checked November 3, 2026. See how we source.

  1. The Open Group, POSIX.1-2024: 4.19 Seconds Since the Epoch pubs.opengroup.org
  2. Python documentation: time — Time access and conversions docs.python.org
  3. MySQL 8.4 Reference Manual: The DATE, DATETIME, and TIMESTAMP Types dev.mysql.com
  4. Phoronix: Linux 5.6 Is The First Kernel For 32-Bit Systems Ready To Run Past Year 2038 phoronix.com
  5. LWN.net: Debian looks forward to 2038 lwn.net