Fixing Clock Skew and Certificate Errors
What You'll Learn
- Why
make's "Clock skew detected" warning and TLS's "certificate is not yet valid" share one root cause - How to tell whether a wrong clock is the culprit using
date/openssl - How to fix the clock and restore both builds and certificate verification
Conclusion (triage pattern)
- However varied the symptoms, the root is one thing: the system clock has drifted from real time
- First confirm the drift is real with
timedatectlanddate -u - If it is, fix the clock with NTP, then re-
touchany files with a future mtime
Assumptions (target environment)
- OS: Ubuntu / Debian / RHEL family (systemd with chrony or systemd-timesyncd)
- Mainly environments where the clock drifts easily: VMs, containers, Raspberry Pi
What is clock skew, and why does it break certificates and builds?
Conclusion: Clock skew is the system clock drifting from real time. Builds see file mtimes in the future, certificates see a validity window (notBefore) in the future, so both get rejected as "from the future."
Clock skew means a machine's system clock is off from the correct time. The direction of the drift changes the symptom.
- Clock is behind (in the past) → a freshly issued certificate is judged "not yet valid"
- Clock is ahead (in the future) → generated files get a future mtime, and build tools warn
The essence of this problem is that a seemingly unrelated build error and certificate error both come from the same time mismatch. A certificate has a time window — notBefore (valid from) and notAfter (valid until) — and make compares file freshness by mtime. Both rely on "the current time," so when that baseline itself is wrong, things break in a chain.
Common sources
- VM suspend/resume or snapshot restore rewinds the clock
- The host clock is already wrong when a container starts
- A dead RTC (hardware clock) battery resets the time on every reboot
- An NFS server and client disagree on the time (file mtimes look like the future)
How do I check whether the clock is wrong?
Conclusion: Check sync status with
timedatectland the current UTC withdate -u, then compare against a trusted external time. A gap of tens of seconds or more points to clock skew.
Start by checking sync status and the current time.
$ timedatectl
Local time: Sat 2026-06-06 12:00:00 UTC
Universal time: Sat 2026-06-06 12:00:00 UTC
RTC time: Sat 2026-06-06 12:00:00
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: no
NTP service: active
System clock synchronized: no is the tell. Next, compare against a trusted external time. An HTTP response Date header is a convenient reference.
$ date -u $ curl -sI https://www.google.com | grep -i '^date:'
If the two times differ by tens of seconds to minutes or more, clock skew is the cause. To avoid confusing this with a time-zone difference, always compare in UTC with date -u.
A wrong time zone (Time zone) is not clock skew. If the UTC value from date -u is correct, a difference in displayed local time is a time-zone issue and does not affect certificates or builds.
How do I fix the "Clock skew detected" build warning?
Conclusion: After fixing the clock, list files with a future mtime via
find . -newermt nowand reset them withtouch. Rebuilding withmake cleanis the most reliable fix.
A typical warning during make:
make: Warning: File 'main.o' has modification time 9876 s in the future make: warning: Clock skew detected. Your build may be incomplete.
This happens because a source or object file's mtime is in the future relative to the current system clock. Since make decides what to rebuild by comparing mtimes, future-dated files break dependency resolution and the build may end up incomplete.
The order is "1) fix the clock, then 2) fix the future mtimes." If you don't fix the clock first, touch just stamps the still-wrong current time again.
# 1. Fix the clock (details in #fix-clock below)
$ sudo timedatectl set-ntp true
# 2. Find files with a future mtime
$ find . -newermt now -type f
# 3. Reset them to the current time
$ find . -newermt now -type f -exec touch {} +The most reliable approach is to discard intermediates and rebuild.
$ make clean && make
If this happens with sources on NFS, sync the clock on both the NFS server and client. Fixing only one side leaves future mtimes stamped by the other, and it recurs.
How do I fix "not yet valid / expired" certificates?
Conclusion: Check notBefore/notAfter with
openssl x509 -noout -dates. If the current time is outside the window, suspect the clock. Fixing the clock usually resolves it without reissuing the certificate.
When the clock is wrong, verification fails even for a valid certificate. Typical messages by tool:
# curl curl: (60) SSL certificate problem: certificate is not yet valid # git clone (https) fatal: unable to access '...': server certificate verification failed # Go-based tools x509: certificate has expired or is not yet valid # apt update E: Release file for ... is not valid yet (invalid for another 5h 30min ...)
The apt "is not valid yet" message is clear evidence of clock skew. Check the certificate's validity window with openssl.
# A local certificate file
$ openssl x509 -in cert.pem -noout -dates
# A remote server's certificate
$ echo | openssl s_client -connect example.com:443 2>/dev/null \
| openssl x509 -noout -datesnotBefore=Jun 5 00:00:00 2026 GMT notAfter=Sep 3 23:59:59 2026 GMT
If the current UTC (date -u) is before notBefore, you get "not yet valid"; if after notAfter, "expired." In both cases the certificate itself is fine, and fixing the clock resolves it.
Before reissuing a certificate or disabling verification with --insecure, always check the clock. If the cause is clock skew, swapping the certificate is pointless, and disabling verification only weakens security. If a CA bundle or incomplete chain is the cause, see Fixing "certificate verify failed".
How do I correct the clock properly?
Conclusion: Enable NTP with
timedatectl set-ntp trueand correct immediately withchronyc makestep. Write the time back to the RTC withhwclock --systohcso it survives reboots.
Enabling NTP sync is the baseline.
$ sudo timedatectl set-ntp true $ timedatectl # confirm: System clock synchronized: yes
When the drift is large, chrony corrects gradually for safety. To jump immediately, use makestep.
$ sudo chronyc makestep $ chronyc tracking # confirm the offset converges near 0
If the time keeps resetting after a reboot (e.g. a dead RTC battery), write the corrected system clock back to the hardware clock.
$ sudo hwclock --systohc
For how NTP sync works and when to choose systemd-timesyncd vs chrony, see Fixing Server Time Skew (NTP sync).
VM / container notes
- A container shares the host kernel's clock. You can't run NTP inside the container, so fix the clock on the host
- A VM can jump in time on resume or snapshot restore. Enable the hypervisor's guest time sync, or run NTP inside the guest
A checklist to prevent recurrence
Conclusion: Make NTP persistent, write the RTC back, and sync time across VMs and NFS pairs, and clock-skew build and certificate errors are largely preventable.
| Measure | Command / setting | Effect |
|---|---|---|
| Keep NTP sync always on | timedatectl set-ntp true |
Auto-corrects clock drift |
| Save correct time to the RTC | hwclock --systohc |
Prevents reset after reboot |
| Detect early with monitoring | Watch chronyc tracking offset |
Catches drift before an incident |
| Sync both NFS server and client | Enable NTP on both hosts | Prevents future-mtime recurrence |
Copy-paste: clock skew diagnosis one-liner
# Check sync status, local UTC, and external time at once timedatectl; echo "--- local UTC ---"; date -u; \ echo "--- remote ---"; curl -sI https://www.google.com | grep -i '^date:'