Embedded Systems and RTOS
In brief: Embedded devices such as controllers, meters, routers, cameras, car modules and medical equipment are where 2038 is most likely to cause real failures. Many run 32-bit processors, use C libraries or real-time operating systems that historically counted time in 32 bits, and stay in service for 15–30 years without software updates. Most RTOS vendors now offer 64-bit time, but only in recent versions and sometimes only as a build option. Devices already in the field keep whatever they shipped with.
| Risk level | Critical (deployed 32-bit fleets with long service lives) · Medium (new designs on current toolchains) |
| Status | Fixes exist in VxWorks 7, QNX SDP 8.0, ESP-IDF 5.0, newlib/picolibc, musl 1.2, glibc 2.34, uClibc-ng 1.0.46+. Deployed devices and older SDKs remain exposed |
| Last reviewed | 2026-10-21 |
2038 status at a glance
- At risk ConfirmedVxWorks 6.x (without RCPL8) and earlierThese have a 32-bit time_t. VxWorks 7 supports 64-bit time_t only in a VSB configured for it.Do: Move to VxWorks 7 with a 64-bit time_t VSB.
- At risk ConfirmedESP-IDF 4.4 and earlier (ESP32)These have a 32-bit time_t. ESP-IDF 5.0 moved to 64-bit.Do: Rebuild firmware with ESP-IDF 5.0 or later.
- At risk Confirmednewlib toolchains built with _USE_LONG_TIME_TOn 32-bit microcontrollers, long-based time_t is 32-bit.Do: Use a toolchain built without _USE_LONG_TIME_T.
- DependsFreeRTOS and Zephyr application codeThe FreeRTOS kernel itself is not affected, but coreSNTP and libc-based application code may be. Zephyr 3.5+ with picolibc is 64-bit, and other libc configurations need checking.Do: Check the C library configuration and any SNTP and time-conversion code.
- DependsQNX 6.x / 7.xtime_t is unsigned 32-bit, which reaches about 2106, but code that casts it to a signed type breaks in 2038. QNX SDP 8.0 uses signed 64-bit.Do: Audit signed casts, or move to SDP 8.0.
Overview
For an embedded product, the width of time is decided by the toolchain's C library and its build configuration, not by the processor alone:
- An RTOS kernel usually counts ticks since boot (often in a 32-bit or 64-bit integer) and has no idea of the calendar date. Tick counters have their own wrap-around periods, which are unrelated to 2038.
- Calendar time comes from an RTC chip, NTP/SNTP, GNSS or a cellular network. It is converted to a
time_tby the C library (newlib, picolibc, the vendor's libc, glibc/musl/uClibc-ng on embedded Linux). If thattime_tis 32-bit signed, the device fails in 2038. - Time also flows into protocols and storage, such as SNTP, TLS certificate validation, log files, flash file systems and fieldbus timestamps, each with its own field widths.
Long product lifecycles make this urgent. Wind River notes that "Embedded devices are built to last. They run for decades without updates" [1]. As early as 2013, LWN pointed out that there "may well be large numbers of embedded 32-bit systems running in 2038" that were deployed years earlier [2]. A controller designed in 2026 on a 10-year-old SDK, sold until 2032 and kept running for 15 years is still in service in 2047.
Technical details
Commercial RTOS
| RTOS | 2038 status | Details |
|---|---|---|
| VxWorks 7 (Wind River) | 64-bit time since 2020 | "VxWorks 7 has supported 64-bit time stamps since 2020", with "64-bit time_t support across kernel and user space" and "No date overflow in 2038" [1]. The time_t width depends on the VSB (VxWorks Source Build) configuration, and toolchains and language runtimes must match it. GCC/Ada changed its VxWorks 7 default in 2021 for this reason [3]. |
| VxWorks 6.9 | Partial, by patch | In 2025 Wind River released RCPL8 for VxWorks 6.9.4.12, which adds Y2038 support to key components for customers who cannot move to VxWorks 7 [1]. Earlier 6.x releases should be treated as affected. |
| QNX Neutrino 6.x / 7.x | Unsigned 32-bit to ~2106 (32-bit targets) | QNX docs: previous releases "used an unsigned 32-bit value for seconds since the start of January 1st, 1970", representable "through approximately the year 2100" [4]. The 7.1 docs say 64-bit QNX targets use a signed 64-bit value [5]. Unsigned means pre-1970 dates are impossible, and code that casts to a signed 32-bit type still breaks in 2038. |
| QNX SDP 8.0 (QNX OS 8) | Signed 64-bit | "This release of QNX OS uses a signed 64-bit value for seconds since the start of 1970", a range that "can be considered infinite" [4]. |
| QNX 4 | Not addressed | A QNX 4 knowledge-base article says the 2038 issue had not been addressed for that product line [6]. |
| Eclipse ThreadX (formerly Azure RTOS / Express Logic) | Kernel tick-based; calendar time from the toolchain | ThreadX's system clock is a ULONG tick counter that starts at zero and wraps [7]. Its POSIX compatibility layer derives clock_gettime from that tick counter [7]. The 2038 exposure therefore depends on the toolchain libc time_t and on add-ons (NetX Duo SNTP, FileX). ThreadX was contributed to the Eclipse Foundation in 2023–2024 under the MIT licence and is "IEC 61508, IEC 62304, ISO 26262, and EN 50128" certified, so it is widely used in safety-relevant long-life products [8]. |
Open-source RTOS and SDKs
| RTOS / SDK | 2038 status | Details |
|---|---|---|
| FreeRTOS kernel | Not affected (ticks since boot) | Richard Barry (FreeRTOS): the kernel measures time from power-on using the tick count. FreeRTOS staff: the kernel provides no date/time functions, so these come from the platform's C library, and "checking whether time_t is 64-bit is a quick test" [9]. |
| FreeRTOS coreSNTP | Affected (as of 2023-12) | FreeRTOS staff confirmed that coreSNTP is the only affected LTS library because "some code does use UTC time". A fix "may come in a future release" [9]. The coreSNTP docs note that 32-bit signed UNIX time ends in January 2038 and that SNTP's own era wraps in February 2036 [10]. See NTP-Era-2036. |
| Zephyr | 64-bit time_t with the default picolibc |
Zephyr 3.5.0 (2023) made picolibc the default C library on most targets [11]. picolibc's sys/_types.h defines __time_t as __int64_t unless the machine overrides it [12]. Projects that select the minimal libc or an external newlib configured with _USE_LONG_TIME_T must check their own time_t (unverified for every board). |
| newlib (GNU Arm Embedded, many vendor toolchains) | 64-bit by default per the 2017 change (release that first shipped it not verified here) | Sebastian Huber's 2017 patch made time_t "a signed integer with at least 64-bits" by default, with --enable-newlib-long-time_t / _USE_LONG_TIME_T to force long. The README warns that this "reintroduces the year 2038 issue" on 32-bit-long targets [13]. Older vendor toolchains, built before about 2018, may still ship a 32-bit time_t (check sizeof(time_t)). |
| ESP-IDF (Espressif ESP32) | 64-bit since v5.0 | "To address the Y2K38 issue, ESP-IDF uses a 64-bit signed integer to represent time_t starting from release v5.0." Its SNTP handling uses a convention that runs to 2104 [14]. ESP-IDF 4.x firmware is affected. |
| TI SimpleLink / TI-RTOS with TI Clang | Configuration-dependent | TI has tracked "Support 64-bit POSIX time_t from TICLANG on FreeRTOS" as an issue [15]. (Details unverified.) |
Embedded Linux on 32-bit ARM and MIPS
Most "smart" devices (routers, NAS boxes, IP cameras, set-top boxes, gateways, HMIs) run embedded Linux on 32-bit ARM (ARMv5/v6/v7) or MIPS32 SoCs. The fix requires all of the following (details in OS-Linux):
| Requirement | Minimum |
|---|---|
| Kernel | 5.1 (time64 syscalls); 5.6 for complete support [16] |
| C library | musl ≥ 1.2.0 (default) [17] · glibc ≥ 2.34 with -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64 [18] · uClibc-ng ≥ 1.0.46 with TIME64 enabled (ARM first, then big-endian and others; build fails on kernels < 5.1) [19] |
| Build system | Yocto ≥ 4.3 "Nanbield" (default) [20] · Buildroot BR2_TIME_BITS_64 (glibc) [21] · OpenWrt via musl |
| File systems | ext4 with ≥ 256-byte inodes, XFS bigtime, or a flash file system with 64-bit or unsigned timestamps. See File-Systems |
| Applications | Rebuilt. No time_t → int/long casts; no 32-bit time fields in formats |
The original uClibc project is no longer maintained. Its successor uClibc-ng added time64 only in 2024 [19]. Many vendor SDKs (BSPs) for 32-bit SoCs are stuck on Linux 3.x/4.x kernels and old uClibc or glibc, and cannot be fixed without a full BSP upgrade.
A practical test from DAVE Embedded Systems shows the behaviour. On a 2038-dated system, a 32-bit-time_t binary prints a 1970 or 2033 date, while the same source built with _TIME_BITS=64 prints the correct 2038 date on Yocto Scarthgap, PetaLinux and Buildroot [21].
Product lifecycles
| Sector | Typical service life (indicative) | Why it matters |
|---|---|---|
| Industrial control (PLCs, RTUs, DCS) | 15–30 years | Rarely patched, often air-gapped. See Devices-Industrial-and-Infrastructure |
| Automotive ECUs and head units | 15–20 years of vehicle life | OTA updates only on recent platforms. See Devices-Automotive-Aviation-Medical |
| Medical devices | 10–20 years | Regulatory re-validation makes updates costly |
| Telecom and networking gear | 10–15+ years | Embedded Linux on MIPS/ARM32. See Devices-Networking-and-IoT |
| Smart meters and utilities | 15–20 years | Large fleets, limited remote update capability |
(Service-life figures are indicative industry ranges, not sourced statistics. See the linked device pages for sourced detail.)
Affected versions / products
| Platform | Safe from | Affected |
|---|---|---|
| VxWorks | 7 (2020+, VSB with 64-bit time_t) [1] |
6.x without RCPL8; earlier [1] |
| QNX | SDP 8.0 (signed 64-bit) [4] | 6.x/7.x 32-bit: unsigned to ~2106, but signed casts break; QNX 4 [4][6] |
| FreeRTOS | Kernel not affected [9] | coreSNTP (as of 2023-12); libc-dependent application code [9] |
| Zephyr | 3.5+ with picolibc [11][12] | Other libc configurations: check |
| ESP-IDF | v5.0 [14] | ≤ v4.4 |
| newlib-based toolchains | Builds without _USE_LONG_TIME_T [13] |
Older or long-time builds |
| Embedded Linux (32-bit) | Kernel 5.6 + musl 1.2 / glibc 2.34+_TIME_BITS=64 / uClibc-ng 1.0.46+ [16][17][18][19] |
Anything older |
Risk & compliance notes
- Inventory by firmware build, not by product name. The same model can ship different SDKs over its life.
- Ask suppliers for attestations covering kernel and libc versions,
sizeof(time_t), file-system timestamp ranges and post-2038 test evidence. See Risk-Assessment-Checklist. - Safety-certified systems (IEC 61508, ISO 26262, IEC 62304) need re-certification for a toolchain change. Budget for it early.
- Watch the near-term dates as well. SNTP/NTP era rollover (2036-02-07), GPS week rollovers, and RTC chips with 2-digit years or a 2099 limit. See NTP-Era-2036, GPS-Week-Rollover and Related-Date-Bugs.
Detection & mitigation
/* drop into any firmware test build */
_Static_assert(sizeof(time_t) >= 8, "time_t is not 64-bit: Y2038 unsafe");
- Check the libc configuration:
_USE_LONG_TIME_T(newlib),_TIME_BITS(glibc), musl version, the uClibc-ng TIME64 option, and the VxWorks VSB setting. - Set the RTC or NTP source to 2038-01-19 03:13:00 UTC on a bench unit and watch logs, TLS handshakes, schedulers and the persisted data across a reboot.
- Static analysis: find casts and stores of
time_tinto 32-bit types. See Lang-C-and-CPP. - See Testing-and-Detection and Remediation-Guide.
See also
- Year-2038-Problem · Operating-Systems · OS-Linux · OS-Android
- Devices-and-Embedded-Systems · Devices-Industrial-and-Infrastructure · Devices-Automotive-Aviation-Medical · Devices-Networking-and-IoT
- NTP-Era-2036 · GPS-Week-Rollover · Year-2106-and-Beyond
References
- Back to the Future and the Year 2038 Problem: Keeping Embedded Systems on Track — Wind River blog, 2025-08-27. VxWorks 7 64-bit time since 2020; RCPL8 for VxWorks 6.9.4.12.
- Pondering 2038 — LWN.net, 2013-08-14. Embedded 32-bit systems still running in 2038.
- [Ada] Size of time_t in newer versions of VxWorks7 — GCC patches (sourceware patchwork), 2021-10-11.
time_tsize must match the VSB (seen in search results). - What time is it? — QNX OS 8.0 Programmer's Guide. Unsigned 32-bit in previous releases; signed 64-bit in 8.0.
- What time is it? — QNX SDP 7.1 Programmer's Guide. 32-bit vs 64-bit QNX targets (seen in search results).
- QNX RTOS v4 Knowledge Base, solution 4631 — QNX. The 2038 issue not addressed for QNX 4 (seen in search results).
- ThreadX POSIX compatibility layer: px_clock_gettime.c (ThreadX v6.3.0 source mirror) and pw_chrono_threadx docs — Pigweed.
tx_time_get()is a wrapping ULONG tick count (seen in search results). - Microsoft opens sources ThreadX — The Register, 2023-11-28 and Microsoft Contributes Azure RTOS to Eclipse Foundation — Embedded Computing Design. Eclipse ThreadX, MIT licence, safety certifications (seen in search results).
- Will the 2038 years problem be happened on IoT reference of FreeRTOS? — FreeRTOS Community Forums, 2023-12-12/13. Answers from FreeRTOS and AWS staff.
- core_sntp_serializer.h — FreeRTOS/coreSNTP on GitHub. Source comments document the 2036 SNTP era overflow and the signed 32-bit UNIX-time limit of 19 Jan 2038 03:14:07 UTC.
- Zephyr 3.5.0 release notes — Zephyr Project and Introducing Zephyr 3.5 — Zephyr Project blog. Picolibc is now the default C library (seen in search results).
- picolibc libc/include/sys/_types.h — picolibc (GitHub).
typedef __int64_t __time_t;(fetched 2026-10-21). - [PATCH] Change time_t to 64-bit by default — newlib mailing list (Sebastian Huber), 2017-09. The 64-bit default and the
_USE_LONG_TIME_Topt-out. - System Time — ESP-IDF Programming Guide v5.5.5 — Espressif. 64-bit signed
time_tfrom v5.0; SNTP to 2104. - Support 64-bit POSIX time_t from TICLANG on FreeRTOS (EXT_EP-9975) — Texas Instruments SIR. TI issue entry (seen in search results).
- [GIT PULL] y2038: core, driver and file system changes — Arnd Bergmann, LKML, 2020-01-29. Linux 5.6 as the base for 32-bit systems beyond 2038.
- musl 1.2.0 released — musl list (Openwall), 2020-02-20. 64-bit
time_ton all 32-bit archs. - glibc NEWS (mirror of glibc.git) — GNU C Library. 2.34
_TIME_BITS=64. - uClibc-ng commit log (time64) — uClibc-ng cgit and [Buildroot] package/uclibc: update to 1.0.46 — Buildroot list, 2024-03. time64 introduced February 2024 for ARM, extended later; requires kernel ≥ 5.1 (seen in search results).
- Release 4.3 (nanbield) migration guide — Yocto Project. 64-bit
time_ton 32-bit targets. - MISC-TN-033: How to cope with Y2038 problem — DAVE Embedded Systems wiki. Bench test results; Buildroot
BR2_TIME_BITS_64.