Stratum 16 Troubleshooting
Fix the NTP "unsynchronized" state on chrony, ntpd and w32tm
1. What stratum 16 really means
In the NTP protocol, the stratum field is an 8-bit integer identifying the distance from the reference atomic clock. Values 1–15 are valid operating strata. Stratum 16 is a sentinel value meaning "unsynchronized" — the daemon has no trusted time source. It is both:
- the initial state on daemon start-up, before any peer stabilises, and
- the fallback state when all configured peers become unreachable or are rejected by the sanity checks.
The difference matters for diagnosis. Freshly-booted stratum 16 with a visible iburst countdown is normal. Stratum 16 after 30 minutes of uptime is a fault.
Note that 16 is not "a very bad stratum" on a continuous scale — it sits outside the scale entirely. A stratum 3 clock is synchronized and usable; a stratum 16 clock is not synchronized at all, and the gap between the two is categorical rather than gradual. If that distinction is new to you, the meaning of each stratum level from 0 to 15 is worth reading before you start changing configuration.
2. 3-step diagnostic on chrony and ntpd
Run these three commands in order. Each one points to the most likely next cause.
chrony
$ chronyc tracking # overall sync status
$ chronyc sources -v # per-source reachability and selection
$ chronyc sourcestats -v # offset/jitter stability per source
ntpd / ntpsec
$ ntpq -p # per-source table
$ ntpq -c rv # read variables: stratum, offset, jitter, dispersion
$ ntpq -c 'rv 0 stratum,offset,frequency,sys_jitter'
Read the output against the three common root causes below.
3. Cause #1 — no reachable source
Signature in chronyc sources: every source shows ? or ~ in the selection column, and reach is 0. Signature in ntpq -p: all peers show .INIT. as their refid.
Fix sequence:
# 1. Test UDP 123 reachability
$ nc -u -vz ntp.rdem-systems.com 123
# or, if nc is not UDP-capable
$ ntpdate -q ntp.rdem-systems.com
# 2. Check firewall state
$ sudo iptables -L -n | grep 123
$ sudo firewall-cmd --list-all | grep ntp
$ sudo ufw status | grep 123
# 3. If blocked, open it
$ sudo ufw allow 123/udp # ufw
$ sudo firewall-cmd --add-service=ntp --permanent && sudo firewall-cmd --reload
Deep dive: the firewall guide covers iptables, firewalld, ufw and Windows Firewall.
4. Cause #2 — offset above the panic threshold
Signature: sources are reachable (reach > 0), but the daemon refuses to step the clock. Logs mention "panic sanity" (ntpd) or "clock jump too large" (chrony).
Default thresholds:
| Daemon | Threshold | Directive |
|---|---|---|
| ntpd | 1000 s | tinker panic 0 (disable) or launch with -g |
| chrony | Configurable (no hard panic) | makestep 1.0 3 in chrony.conf |
| w32time | Varies (MaxPosPhaseCorrection / MaxNegPhaseCorrection) | Registry under HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config |
Fix — chrony
# One-shot step (manual)
$ sudo chronyc makestep
# Persist: allow step for first 3 clock updates if offset > 1s
# in /etc/chrony/chrony.conf
makestep 1.0 3
Fix — ntpd
# One-shot step at start-up (past panic threshold)
$ sudo systemctl stop ntp
$ sudo ntpd -gq # query once with -g allowed
$ sudo systemctl start ntp
5. Cause #3 — all sources rejected by selection
Signature: sources are reachable, offsets are small, but the selection column shows x (false ticker) or - (outlyer) on every peer. The daemon has no majority to agree with, so it stays at stratum 16.
Usually means you have an even number of sources and they split 50/50, OR one source is wildly wrong and drags the median. Fixes:
- Configure at least 4 sources. With 3, any one outlier creates deadlock; with 4 the intersection is robust.
- Diversify upstream: do not use 4 servers from the same operator/ASN. See the NTP source comparison for good dual-operator options.
- Identify the outlier with
chronyc sourcestats -v— look for one source with offset > 3× the others — and treat it as a false ticker.
6. Windows w32tm equivalent
On Windows, stratum 16 manifests as the unsynchronized state of w32time or TimeState::StateNoSync.
:: Query status
> w32tm /query /status
:: Force resync from authoritative peer
> w32tm /resync /force
:: Reconfigure manual peer list
> w32tm /config /manualpeerlist:"ntp.rdem-systems.com time.cloudflare.com" /syncfromflags:manual /update
> net stop w32time && net start w32time
> w32tm /resync /force
If the resync fails, check Windows Firewall allows outbound UDP 123. On a domain-joined machine the cause is usually the Active Directory hierarchy rather than the source itself — the Windows Time troubleshooting hub decodes the PDC-emulator chain, the w32tm status fields and the Event IDs in depth.
7. VM and hypervisor gotchas
Virtualisation adds a second time authority competing with NTP. Turn it OFF inside guests that run chronyd/ntpd:
- Hyper-V: uncheck "Time synchronization" in the Integration Services of each VM; set the Hyper-V service startup to manual via PowerShell if you want to keep it for nested VMs only.
- VMware: open-vm-tools installs
vmtoolsdwhich can sync the guest to the host. Disable in/etc/open-vm-tools/tools.confwithtime.synchronize.tools.startup = falseand related flags. - KVM / libvirt: avoid
<clock offset="host">with periodic sync. Use<clock offset="utc"/>and let chronyd handle it.
After disabling host-guest sync, restart chronyd and wait 1–3 poll intervals (64–256 s default) for sync to lock.
Related diagnostic pages:
After the fix — related sites:
- Measure jitter, offset, latency → ntp-tester.eu
- Produce NIS 2 / ISO 27001 audit evidence → online-ntp-validator.com
- Enterprise reference architecture → ntp.rdem-systems.com