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.
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.
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