This caught us in the middle of a routine product update on a 32-bit ARM platform, where everyone involved had assumed the toolchain settled it years ago. A 32-bit time_t stops counting on 19 January 2038, inside the service life of hardware shipping this quarter. The fix — building against a 64-bit time_t — has been in the kernel and the C libraries for years, and OpenEmbedded-Core applies it by default from Yocto 4.3 onward. What your build will not do is tell you when it has not been applied: the check that catches a 32-bit time_t binary is a warning rather than an error, it is switched off for every Rust component, and it never looks at prebuilt vendor libraries or at the filesystem underneath.

We found it by accident, and not on a target. A build machine came up with the wrong date, and chasing down what that broke led into a library in our own image still being compiled against a signed 32-bit time_t while everything around it had moved on. Nothing in the product update concerned timekeeping, and nobody had gone looking. The kernel and glibc had supported 64-bit time for years. How a single library ends up on the wrong side of that line is the subject of what follows.

A signed 32-bit time_t counts seconds since 1970 and reaches its maximum value of 2147483647 at 03:14:07 UTC on 19 January 2038, after which it wraps to December 1901. That is just under twelve years away, and hardware entering production this quarter will still be installed when it arrives.