In 2006, servers began behaving strangely. Scheduled tasks stopped running, database connections froze and processes became unresponsive. There was no cyberattack, no hardware failure and no obvious explanation. The culprit was something far more mundane: a calculation involving time.
AOLserver, the open-source web server once developed by AOL, had a workaround for a situation that was never really expected to happen: a database request that should, effectively, never expire. Rather than handling that special case explicitly, the software used a timeout of roughly one billion seconds into the future. It seemed like more than enough. It wasn’t.
On 13 May 2006 at 01:27:28 UTC, that interval pushed a calculation beyond the largest value a signed 32-bit Unix timestamp could represent. The result was a numerical overflow: a date that should have been in the future suddenly appeared to be in the past, and requests began expiring almost as soon as they arrived. The fix was simple — change the configuration and reduce the timeout.
What the incident revealed, however, was far more significant. The so-called “Year 2038 problem” does not necessarily begin in 2038. It begins whenever a system tries to represent a date that its clock cannot hold. And that means the problem has already started.
The clock that runs out in 2038
The roots of the problem lie in a technical decision made decades ago. Unix systems traditionally represent time as the number of seconds elapsed since 1 January 1970 at 00:00:00 UTC — the so-called Unix epoch. On many older platforms, that value is stored in a signed 32-bit integer, commonly known as time_t.
A number of this type can represent values from −2³¹ to 2³¹−1, which means the largest number of seconds it can store after 1970 is 2,147,483,647. The counter reaches that value at 03:14:07 UTC on 19 January 2038.
One second later, it overflows. Instead of continuing upwards, the number jumps from 2,147,483,647 to −2,147,483,648. To a system interpreting that number as a date, the clock has effectively travelled backwards in time: the timestamp suddenly represents 13 December 1901.
The problem has been known about for decades, and modern 64-bit systems have largely moved beyond it. GNU’s Gnulib documentation, for example, identifies the issue specifically on platforms that still use a 32-bit time_t and documents measures for supporting timestamps beyond 2038.
But there is a catch. Having a 64-bit processor does not mean that every timestamp passing through your system is 64-bit. And that is where things get interesting.
Your server can be modern and still have a 32-bit clock
Imagine a modern server: a 64-bit processor, an up-to-date operating system, a current kernel, plenty of memory. Everything looks ready for 2038.
Now imagine that the same server stores a date in a database field that still uses a 32-bit representation. Or sends a timestamp to an old device through a protocol that allocates just four bytes for the time. Or reads a binary file created decades ago. Or relies on a third-party library originally compiled with a 32-bit time_t.
The server is still 64-bit. The timestamp isn’t.
The problem does not necessarily live in the computer doing the calculation. It can live anywhere along the path where the timestamp is stored or transmitted. That is why the Year 2038 problem is less like a clock that suddenly stops in 2038 and more like a chain of components in which a single outdated link can still cause failure.
MySQL still has a problem called TIMESTAMP
This is probably the most relevant example for web developers. The MySQL 8.4 documentation still describes an important limitation for the TIMESTAMP data type: depending on the platform and implementation, its range can extend only as far as 19 January 2038 at 03:14:07 UTC.
That means we are not talking solely about forgotten servers sitting in an old server room. A modern application can be running on completely up-to-date infrastructure and still have a Year 2038 problem, simply because someone chose TIMESTAMP to store a date that was supposed to remain valid for decades.
Think about an application recording the end of a contract, the expiry of a subscription, a data-retention deadline, the validity of a software licence, scheduled maintenance for a piece of equipment, or the expiry of a security certificate. If one of those dates extends beyond the representation’s limit, the problem appears when the date is calculated or stored, not necessarily in 2038.
MySQL also provides DATETIME, which is documented as supporting dates up to 9999. The difference between choosing one data type and another may seem trivial when a system is being built. Decades later, it could be the difference between a valid date and a broken application.
The bug has already hit mortgages — and certificates could be next
This is probably the most counter-intuitive part of the story. If a system calculates a date 30 years into the future, it does not have to wait 30 years to discover that the result cannot be represented.
A 30-year mortgage taken out in 2008 could already have produced a final date beyond the 2038 limit. A 20-year maintenance plan created in 2018 could have run into the same problem. And a ten-year certificate issued today is already heading into the danger zone.
That is why exposure to the Year 2038 problem is appearing gradually. There will not necessarily be a single morning in January 2038 when every vulnerable computer suddenly stops working. Some systems will fail earlier, others will break as they begin dealing with increasingly distant dates, and some may only be discovered when nobody remembers why a particular field was originally defined as a 32-bit integer.
This is what makes the AOLserver episode worth remembering. It did not involve a sophisticated attack or a mysterious hardware fault — it was just arithmetic, a number that was too large. It is documented as one of the earliest known manifestations of the problem, and the lesson it offers remains relevant nearly two decades later: a system does not have to reach 2038 to have a 2038 problem.
Who is actually at risk?
The answer is less straightforward than simply saying “old computers”. Potentially vulnerable systems include 32-bit operating systems and ABIs, legacy applications, databases with restricted timestamp fields, old binary formats, firmware and embedded devices.
And embedded systems may be the hardest problem of all. A smartphone or cloud server can receive frequent software updates, but an industrial controller, medical device, aviation system or piece of factory equipment may remain in service for decades, with little or no practical opportunity to replace or update its software. Many of these systems were designed to last a very long time, and some were built when 2038 seemed so far away that preparing for it hardly appeared worth the effort. Now the future is getting closer.
Linux has already started addressing the problem
The good news is that the industry has not been standing still. NetBSD 6.0 introduced support for 64-bit Unix time in 2012, including on 32-bit architectures, alongside compatibility mechanisms. In Linux, important changes arrived with kernel 5.1 in 2019, while subsequent releases expanded support for 64-bit time_t on 32-bit systems. glibc 2.34, released in 2021, made it possible for configurations traditionally using 32-bit timestamps to switch to a 64-bit time_t by compiling with _TIME_BITS=64.
But there is one particularly important word here: compilation. Updating the library does not automatically turn every old program into a Year 2038-safe application, because an old binary may continue using a 32-bit representation. In other words, updating the operating system may not be enough — sometimes the software itself needs to be recompiled. And that is precisely the kind of detail that can remain hidden for years.
The real problem is the systems nobody remembers
It is tempting to think of the Year 2038 problem as a late-arriving version of Y2K, but there is an important difference. Y2K received enormous attention because almost everyone understood the problem: business systems had stored years using only two digits.
The Year 2038 problem is far more fragmented. It can be hiding inside a library, a database field, a network protocol, a file format, firmware, a piece of equipment bought 15 years ago, a program nobody maintains any more, or — perhaps most importantly — a third-party dependency that works perfectly well today.
That may be the greatest risk. It is relatively easy to check whether your main server uses 64-bit architecture. It is considerably harder to check every place a timestamp can travel.
How to prepare for 2038
The most obvious solution is to stop using 32-bit representations for time wherever possible. In software, that means using explicitly sized types such as int64_t where appropriate, and ensuring that 32-bit platforms use a 64-bit time_t. On Linux systems using glibc, this may involve compiling with _TIME_BITS=64 and, in certain configurations, also _FILE_OFFSET_BITS=64.
The Microsoft ecosystem is different. Windows internally represents time as the number of 100-nanosecond intervals since 1 January 1601, stored in a signed 64-bit integer, so the operating system does not suffer from the classic Unix Year 2038 overflow. That does not mean every Windows application is automatically protected against every possible date-related problem.
The most important rule remains the same: test software with dates beyond 2038. Testing only with today’s date is not enough. A system that works perfectly in 2026 may fail when someone enters 2040, and those dates need to become part of automated testing — permanently, not just as part of a one-off audit.
What if the system cannot be upgraded?
This is where embedded systems become particularly difficult. For some legacy equipment, replacing the entire software stack or hardware simply is not an option.
One possible workaround is to abandon the traditional Unix epoch and use a custom epoch. If the counter starts on 1 January 2000 rather than 1970, for example, a signed 32-bit integer gains several additional decades before reaching its limit.
It is a compromise. It does not remove the limitation; it simply moves the problem further into the future. For systems that need to operate for decades, that may be enough — provided every component involved agrees on the same representation. And that is precisely where compatibility engineering becomes so important.
The next Y2K?
Perhaps. But the most interesting thing about the Year 2038 problem is that it does not need a dramatic “doomsday” moment. It is already here. Software that calculates a sufficiently distant date can encounter the problem today, a database can reject a date that looks perfectly reasonable, a certificate can be interpreted incorrectly, and an industrial device can continue counting time using a representation designed when 2038 seemed like an unimaginably distant future.
The biggest danger, then, is not that every computer will suddenly stop working at 03:14:08 UTC on 19 January 2038. The danger is quieter: that apparently modern systems continue to carry small pieces of old software, old formats and old technical decisions — until somebody finally asks them to calculate a date that no longer fits.
AOLserver demonstrated that in 2006, three decades before the deadline it was supposed to belong to. And perhaps that is the best way to think about the Year 2038 problem: 2038 is not a starting date. It is a limit. Every time a system tries to look beyond it, the future may already have arrived.