Why some systems may break in 2038
Unix systems represent time as the number of seconds since the Unix epoch:
1970-01-01 00:00:00 UTC
This is stored in the C type time_t. On older systems, it’s typically a 32-bit signed integer and therefore can represent time in the range:
-2,147,483,648 to 2,147,483,647
Negative values are used to represent times before 1970. The upper bound of 2,147,483,647 seconds since the epoch corresponds to:
19 Jan 2038 03:14:07 UTC
One second later, at 2,147,483,648, the counter overflows and the value wraps around to -2,147,483,648, which corresponds to:
13 Dec 1901 20:45:52 UTC
This breaks systems that store or compute time using time_t, since any future timestamp beyond that point becomes negative and invalid. Time comparisons, sorting, durations, certificate checks, and scheduling logic may all fail or behave unpredictably.
This is known as the Year 2038 problem (Y2K38). Unlike Y2K, which was about date formatting, it’s a fundamental binary overflow issue.
The problem is largely solved on modern 64-bit platforms, where time_t is already 64-bit1. But many embedded devices such as routers, controllers, security cameras, sensors, and IoT devices, often go unpatched and may remain in use for decades, making them vulnerable in 2038.
To check your system, try:
date -d @2147483648
If it fails with “invalid date”, the system’s time functions or the date utility itself are likely built using a 32-bit time_t limit.
To confirm the size of time_t for newly compiled programs, use this C code:
#include <stdio.h>
#include <time.h>
int main() {
printf("sizeof(time_t): %zu\n", sizeof(time_t));
return 0;
}
Then run:
gcc check_time_t.c -o check_time_t
./check_time_t
If it prints 4, your system uses 32-bit time. If it prints 8, it uses 64-bit and is safe.
You can also check the architecture:
uname -m
Architectures like x86_64 and aarch64 usually use a 64-bit time_t. Architectures like i686, mips, and armv7l often still use 32-bit time_t, unless explicitly rebuilt with 64-bit time support.
It’s a far-off issue, but good to be aware of.
-
It’s worth noting that this can break older 32-bit precompiled binaries on a modern 64-bit system because they expect shared libraries to use a 32-bit
time_t. ↩︎