w32time Hierarchy and Drift: Keeping Windows Server Time Accurate

Run w32tm /query /status on a newly provisioned Windows Server VM and the first three lines report the source, the stratum and the poll interval. On a standalone instance the source is usually VM IC Time Synchronization Provider — a Hyper-V synthetic clock with no independent verification. For an IIS-only host that is tolerable; for a machine issuing Kerberos tickets or validating certificates it is not.

How the w32time hierarchy actually resolves

Windows time is not a single service call. The W32Time service runs in two modes: a client layer that samples one or more upstream time sources, and a server layer that answers NTP requests from downstream machines on UDP port 123. Domain members hold the client role; the PDC emulator of the forest root domain should hold the server role, and every other domain controller points at it. In a single-server deployment on a Windows VPS with full administrator access the same machine is frequently both client and NTP server, which makes the configuration easier to reason about but no less necessary.

The hierarchy is driven by HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Parameters. The value Type selects the role: NT5DS means follow the AD domain hierarchy, NTP means use a manual peer list, NoSync disables inbound correction, and AllSync does everything. A standalone IIS box using NT5DS with no domain to talk to will fall back to local clock and drift; check with w32tm /query /configuration and look at the Type: line before blaming the hypervisor.

Each hop adds error: a stratum-1 source is directly attached to a reference clock, and a stratum-2 server carries the accumulated jitter of its parent. Keep the hierarchy shallow (strata 2 to 4) and never chain five or six internal relays.

Configuring an external peer list correctly

Point a standalone server or the PDC emulator at a real NTP pool, never at time.windows.com alone — it is rate-limited and often unreachable. Use a vendor pool or your own GPS-backed relay. This sequence sets three peers, enables reliable mode and restarts the service:

w32tm /config /manualpeerlist:"0.pool.ntp.org,0x8 1.pool.ntp.org,0x8 ntp.example.net,0x8" /syncfromflags:manual /reliable:yes /update
net stop w32time && net start w32time
w32tm /resync /force
w32tm /query /status
w32tm /query /peers

The 0x8 flag requests client mode; the default is symmetric active, which makes the client also try to serve time. The selection algorithm discards falsetickers, so four sources from different operators beat four hosts from one provider. /reliable:yes marks the machine as a trustworthy source for downstream clients.

After the resync, verify with w32tm /monitor. On a domain controller it prints the offset of every reachable domain controller against its own clock; large positive or negative values on one branch of the tree point at that specific DC’s upstream, not at the whole domain. The Stratum and Offset columns are the two to watch.

Reading the status output and the registry

Command / valueLocationWhat it tells you
w32tm /query /statusCLISource, stratum, poll interval, last successful sync, clock offset
w32tm /query /peersCLIEvery configured peer with state and offset
w32tm /stripchart /computer:hostCLILive offset samples against a named peer
TypeHKLM\SYSTEM\CurrentControlSet\Services\W32Time\ParametersNT5DS, NTP, NoSync or AllSync
NtpServersame keyManual peer list used when Type = NTP
MaxPosPhaseCorrectionsame keyLargest forward step allowed (default 48h, in seconds)
Event ID 35System log, W32TimeThe time service is not able to synchronize
Event ID 37System log, W32TimeThe time provider has not been able to reach a source
Event ID 50System log, W32TimeTime service is using a fallback source

A poll interval of 1024 seconds (about 17 minutes) is normal for a stratum-3 client; the service starts at 64 seconds and backs off as the clock proves stable. Source: Local CMOS Clock with a stratum of 0 means no sync has ever succeeded.

Event ID 129 in the System log is worth grepping for on virtual machines: it reports a time service adjustment that was too large to be a normal correction. On Hyper-V guests this usually means the synthetic clock and the NTP client are fighting. Disable the VM time integration component or the guest vmictimesync device and let exactly one mechanism own the clock.

Measuring drift instead of guessing at it

Run a stripchart against two independent peers for a few minutes and compare the offset pattern. A steady ramp of milliseconds per minute is ordinary crystal drift; steps of hundreds of milliseconds are a scheduling problem — a host whose vCPUs are overcommitted falls behind while descheduled, then jumps forward.

w32tm /stripchart /computer:ntp.example.net /samples:10 /dataonly
# Output: 12:04:11, +0.0038s   12:04:13, +0.0041s ...
# A ramp of ~0.3ms/min is normal; steps >100ms indicate CPU steal.

If you are testing a host before you commit to it — for instance when comparing Windows Server plans — a ten-minute stripchart at idle and again under a compile or IIS load test is a more honest measure of timer quality than any spec sheet. Servers with a stable, low offset curve are the ones that will not produce mysterious Kerberos or TLS failures six months later.

Kerberos, TLS and the 5-minute window

Domain authentication fails when the client clock and the KDC’s clock differ by more than Maximum tolerance for computer clock synchronization — 5 minutes by default, under Computer Configuration\Windows Settings\Security Settings\Account Policies\Kerberos Policy in Group Policy. The error surfaces as STATUS_TIME_DIFFERENCE_AT_DC (0xC0000133) or a misleading “security database does not have a computer account” prompt.

TLS validation compares NotBefore and NotAfter against the local clock, so a host three days behind rejects a fresh certificate as not yet valid and one a day ahead rejects it on expiry day. Both report SEC_E_CERT_EXPIRED (0x80090328) in the Schannel logs.

Making the PDC emulator authoritative

In an AD domain only the PDC emulator should go to the internet; every other DC and member uses NT5DS. On the PDC emulator, set /reliable:yes and confirm that AnnounceFlags under W32Time\Config is 5 (always reliable + time server enabled). Otherwise downstream DCs may ignore it in favour of a machine closer in the AD topology.

If the PDC emulator role moves, the time configuration does not follow it: the new holder keeps NT5DS and starts syncing from itself. Re-apply the peer config on the new role holder, then run w32tm /resync /rediscover on every DC.

A short verification checklist

  • w32tm /query /status shows a real Source, not Local CMOS Clock, and a Last Successful Sync Time within the poll interval.
  • w32tm /query /peers lists at least three peers with no persistent Pending state.
  • Event ID 35/37/50 counts in the System log are zero over the last 7 days.
  • UDP 123 is open inbound only where the server is actually meant to serve time; do not expose it on an IIS-only host.
  • The registry Type value matches the machine’s role — NT5DS for members, NTP with /reliable:yes for the root source.

Five minutes of checking on every new instance catches a class of failures that otherwise take a week to diagnose. Record the offset baseline alongside the build notes.

Leave a Comment