HomeNewsletterCommunityMVP FeedToolsArchiveBlogToday's NewsAboutServicesQuick Links Subscribe free
← Back to Blog
Windows Update Windows UpdateWindows Time Servicew32tmKerberosTLSActive DirectoryTroubleshootingEndpoint Management

A clock 12 minutes out breaks Windows Update, and the error never mentions time

IA
Imran Awan
23 August 2026

A device stops scanning for updates. The error is a hex code that mentions security, or a network, or a certificate. It does not mention the clock. So nobody checks the clock.

That is the whole failure. Windows Update reaches Microsoft over HTTPS, and in an Active Directory environment it also touches Kerberos on the way to a WSUS or Configuration Manager server. Both treat the local system clock as a security input. Move the clock far enough and they stop trusting the device, and neither says so in plain English.

The short version

Kerberos has a documented default tolerance of 5 minutes between a client clock and the domain controller clock, so a device twelve minutes out is more than twice outside it. TLS has no fixed number: chain validation compares a certificate's NotBefore and NotAfter against whatever the local clock says, which is why CertVerifyTimeValidity in crypt32.dll uses the current time when you pass it no time at all. The Windows Update error Microsoft's own troubleshooting library ties to the clock is 0x80072f8f, and the text Windows prints for it is "A security error occurred" - five words, none of them about time. So measure the skew with w32tm /stripchart, ask w32tm /query /source who owns the clock, and read the Time-Service log before you touch SoftwareDistribution.

The problem: the error you get never mentions the clock

Start with the Windows Update error code Microsoft explicitly ties to time. Its support article for 0x80072f8f opens by saying the error "typically indicates issues that affect SSL negotiation because of out-of-sync clock settings or untrusted SSL certificates". Two causes, one code.

Now ask Windows what that code means. certutil -error is the fastest local decoder and needs no elevation, so it is safe to run on a user's machine mid-incident.

Command Prompt - decode the code you were handed
certutil -error 0x80072F8F # The one Windows Update code Microsoft documents as clock-related. 0x80072f8f (WinHttp: 12175 ERROR_WINHTTP_SECURE_FAILURE) -- 2147954575 (-2147012721) Error message text: A security error occurred CertUtil: -error command completed successfully. certutil -error 0x800B0101 # For contrast, a Windows error string that DOES name the clock. 0x800b0101 (-2146762495 CERT_E_EXPIRED) -- 2148204801 (-2146762495) Error message text: A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file. CertUtil: -error command completed successfully. # Both decoded on the lab device: Windows 11 25H2, build 26200.9168. # CERT_E_EXPIRED tells you where to look. ERROR_WINHTTP_SECURE_FAILURE does not.

That contrast is why this failure survives in fleets for months. Windows is perfectly capable of naming the system clock in an error string - CERT_E_EXPIRED does it in so many words. The code Windows Update actually surfaces resolves to a WinHTTP facility error whose entire message is five words long, and one of them is not "time".

So the symptom class is broader than one code. A device that cannot scan, cannot download, or fails a WSUS scan with a generic transport, certificate or trust error is a candidate for a clock problem. Treat the code as a hint about which layer failed, not as a diagnosis.

Watch out: the reflex fix for "Windows Update is broken" is to stop wuauserv and rename C:\Windows\SoftwareDistribution. If the real cause is clock skew, that does two bad things and no good ones. It throws away the download cache and the local scan history, which is the evidence you would have used to date the onset of the problem, and it leaves the clock exactly as wrong as it was. The device fails again on the next scan and you have lost the timeline.

There is a second reason clock problems hide. In a domain the operating system usually papers over small skew on its own - Microsoft's Kerberos guidance says "Typically, if the clocks aren't synchronized, Windows can resynchronize them automatically." So the device limps and self-corrects for weeks. Then it loses its time source entirely, drift accumulates unopposed, and one morning the update stack falls over.

Why it happens: two time-sensitive gates sit in front of every scan

Before the update stack does anything interesting, the device has to prove who it is to something. There are two independent gates, and each uses the clock as an input.

Gate one: TLS certificate validity is evaluated against your clock

Every Windows Update endpoint is HTTPS. Validating the server's certificate chain means checking that each certificate is currently inside its validity window, and "currently" is the operative word. Windows does not consult an external notion of now. It reads the local clock.

The API contract says so. CertVerifyTimeValidity, exported from crypt32.dll, takes a pointer to the comparison time and a pointer to the certificate, and Microsoft documents the parameter plainly: "If NULL, the current time is used." It returns minus one if your comparison time is before the certificate's NotBefore, plus one if it is after NotAfter, and zero if the time is valid. The certificate is fixed; the verdict is not. Any code path passing NULL is asking the local clock to arbitrate trust.

That is also why there is no single number for "how much skew breaks TLS" - it depends on the width of the window on the certificate in front of you. A long-lived server certificate issued last year survives twelve minutes of skew without blinking. A certificate issued in the last few minutes, which is what short-lived and automatically rotated certificates look like, can be "not yet valid" on a device whose clock runs slow. That is a minus-one return from a healthy device talking to a healthy service.

Context: Windows has a partial defence here. The UtilizeSslTimeData value under the W32Time Config subkey controls secure time seeding, which Microsoft describes as using "multiple SSL timestamps to seed a clock that's grossly inaccurate". It is documented as defaulting to 1 on every version that has the feature, except Windows Server 2025 where the default is 0, and it measures 1 on the lab device. Secure time seeding is a floor for absurd clocks, not a substitute for a working time source, and it will not save you from twelve minutes of drift.

Gate two: Kerberos has a documented number, and it is five minutes

The Kerberos gate has an actual policy behind it. The setting is Maximum tolerance for computer clock synchronization, at Computer Configuration\Windows Settings\Security Settings\Account Policies\Kerberos Policy, documented as determining "the maximum time difference (in minutes) that Kerberos V5 tolerates between the time on the client clock and the time on the domain controller that provides Kerberos authentication".

The default in the Default Domain Policy is 5 minutes. Permitted values run from 1 to 99,999, and Microsoft's own best-practice advice is to leave it at 5. The tolerance exists for replay protection: "To prevent 'replay attacks,' the Kerberos v5 protocol uses time stamps as part of its protocol definition."

The Kerberos troubleshooting guidance restates it operationally - "The difference in time between the domain controller and the client computer or the target server must be less than five minutes" - and when it is not, the protocol error is KRB_AP_ERR_SKEW, code 0x25. That guidance maps Event ID 4 carrying KERB_AP_ERR_SKEW to a single instruction: "Make sure that the computer clocks are synchronized".

So a twelve-minute clock is a specific, meaningful number. It is not near the boundary; it is more than twice the documented default, which puts every Kerberos exchange on that device outside the window the domain controller will accept. For update triage that bites in two places: managed scan targets like WSUS with Windows authentication or a Configuration Manager management point are domain resources reached with domain credentials, and the time service itself is authenticated with Kerberos.

Gotcha: inside a forest, NTP is not anonymous. Microsoft documents that "the Windows Time service uses the computer's Kerberos session key to create authenticated signatures on NTP packets that are sent across the network", and that "if the returned NTP packet is not signed with the computer's session key or is signed incorrectly, the time is rejected". A device whose Kerberos is unhappy can therefore be unable to obtain the authenticated time that would have fixed its Kerberos. That loop is why some devices sit broken indefinitely instead of self-healing, and why the trust chain and the time chain have to be diagnosed together.

Where the clock is supposed to come from

The Windows Time service has four components, which Microsoft names as the Service Control Manager, the Windows Time Service Manager, Clock Discipline, and the time providers. The providers are the pluggable part: NtpClient is the input provider that fetches samples, NtpServer is the output provider that answers other machines, and Clock Discipline moves the clock - either adjusting the clock rate to converge slowly or setting the time outright when the gap is too large to slew. Accuracy is expressed as a stratum, counting hops away from a reference clock: "As a computer's stratum number increases, the time on its system clock may become less accurate."

Which source a device uses is decided by the Type value, and there are exactly four.

TypeWhat it meansWhere you see it
NT5DSSynchronise with the Active Directory domain hierarchy. Documented default for domain members.The normal state for a managed endpoint. The device locates a domain controller and takes authenticated time from it.
NTPSynchronise with the servers listed in NtpServer. Documented default for stand-alone clients and servers.Workgroup machines, and domain members that were manually reconfigured and never put back.
AllSyncUse every available mechanism. Documented: "If the client is unable to synchronize time with the domain hierarchy, the time source automatically falls back to the time source specified by the NtpServer setting."Rare in the field, and the one that would have prevented the failure below.
NoSyncDo not synchronise with anything. The local clock is authoritative.Correct only on the root of a time hierarchy. On an endpoint it is a silent time bomb.

Note what is missing from NT5DS: a fallback. A domain member set to NT5DS that cannot locate a domain controller does not quietly reach out to time.windows.com instead - it runs free on the motherboard clock. That is exactly the state the lab device was in, and the next section is the measurement that proved it.

How to verify: measure the skew, then find out who owns the clock

Two questions, and they are independent. How wrong is the clock right now? and is anything keeping it right? A device can pass the first and fail the second, which is the dangerous combination: it looks healthy today and will not be healthy next week. Work the steps in order. None of them changes the machine.

Step 1: measure the offset against a source you trust

Do not read the taskbar clock. It rounds to the minute, it shows local time, and a device eleven minutes out looks identical to one that is right unless the observer is holding a reference. Use w32tm /stripchart, which Microsoft documents as displaying "a strip chart of the offset between this computer and another computer".

Command Prompt - measure the actual offset (read-only)
w32tm /stripchart /computer:time.windows.com /samples:5 /dataonly # /dataonly drops the ASCII graphic and gives numbers you can paste into a ticket. Tracking time.windows.com [51.145.123.29:123]. Collecting 5 samples. The current time is 8/23/2026 11:38:20 AM. 11:38:20, -01.8794386s 11:38:22, -01.8796936s 11:38:24, -01.8987572s 11:38:26, -01.8934743s 11:38:28, -01.8939608s w32tm /stripchart /computer:time.windows.com /samples:2 # Without /dataonly you also get d: the round-trip delay and o: the offset. Tracking time.windows.com [51.145.123.29:123]. Collecting 2 samples. The current time is 8/23/2026 11:38:29 AM. 11:38:29, d:+00.0168527s o:-01.8928284s [ * | ] 11:38:31, d:+00.0277306s o:-01.8881553s [ * | ] # Real measurement from the lab device. Offset stable at about -1.89 seconds # across five samples, with 17-28 ms of round-trip delay. Stable matters: a # single sample cannot tell skew apart from a slow network path.

Read three things out of that. The sign gives direction - negative means the local clock is behind the reference. The consistency across samples says it is real skew rather than one congested packet. And d:, the round-trip delay, is your confidence interval: an offset smaller than the delay is noise, an offset of seconds against a delay of milliseconds is a finding.

Tip: you can run /stripchart on a machine whose time service is running, because Microsoft documents that for this parameter "the NTP client uses an ephemeral UDP source port to communicate to the server to prevent conflicts with the built-in NTP client". That is not true of /resync, which is documented as requiring UDP 123 as the source port. So /stripchart is a measurement and /resync is an intervention. Keep them in that order.

Step 2: ask who the device thinks owns its clock

An offset of 1.89 seconds sounds like nothing. It is well inside the Kerberos tolerance and will not break a handshake. Step 2 is where the lab device stopped looking healthy.

Command Prompt - w32tm /query /source and /status /verbose
w32tm /query /source Local CMOS Clock w32tm /query /status /verbose Leap Indicator: 3(not synchronized) Stratum: 0 (unspecified) Precision: -23 (119.209ns per tick) Root Delay: 0.0000000s Root Dispersion: 0.0000000s ReferenceId: 0x00000000 (unspecified) Last Successful Sync Time: unspecified Source: Local CMOS Clock Poll Interval: 10 (1024s) Phase Offset: 0.0000000s ClockRate: 0.0156250s State Machine: 0 (Unset) Time Source Flags: 0 (None) Server Role: 0 (None) Last Sync Error: 1 (The computer did not resync because no time data was available.) Time since Last Good Sync Time: 4178.2576831s # Real output, domain-joined Windows 11 25H2 laptop. Every line here is a red flag.

Source: Local CMOS Clock is the headline: the device is not taking time from anything. It is reading the battery-backed clock on the motherboard and calling that authoritative. Microsoft's guidance on large offsets describes exactly this handover - "When Windows starts, the kernel pulls the current time from the BIOS. This current time is used as the initial time until the W32Time service can sync up with another time source." On this device the second half never happened.

Leap Indicator: 3(not synchronized) with Stratum: 0 (unspecified) is the service admitting it; a synchronised domain member reports leap indicator 0 and a stratum one greater than its source. Last Successful Sync Time: unspecified paired with Time since Last Good Sync Time: 4178.2576831s says there has never been a successful sync and the service has been failing for about seventy minutes. Last Sync Error: 1 (The computer did not resync because no time data was available.) is the cause in one line - not "access denied", not "wrong signature". No data arrived at all.

This is the teaching point of the whole article. The measured offset was under two seconds, so a skew check alone would have passed this device. The service state says the clock is unmanaged and drifting, and the only thing between it and a Kerberos-breaking offset is the quality of the crystal on that motherboard.

Step 3: read the configuration and the peer list

Command Prompt - configuration and peers (abridged real output)
w32tm /query /configuration [Configuration] EventLogFlags: 2 (Local) MaxNegPhaseCorrection: 4294967295 (Local) MaxPosPhaseCorrection: 4294967295 (Local) MaxAllowedPhaseOffset: 300 (Local) UpdateInterval: 30000 (Local) [TimeProviders] NtpClient (Local) DllName: C:\WINDOWS\system32\w32time.dll (Local) Enabled: 1 (Local) InputProvider: 1 (Local) SpecialPollInterval: 3600 (Local) Type: NT5DS (Local) NtpServer (Local) DllName: C:\WINDOWS\system32\w32time.dll (Local) Enabled: 0 (Local) InputProvider: 0 (Local) w32tm /query /peers #Peers: 1 Peer: State: Pending Time Remaining: 2173.0792976s Mode: 0 (reserved) Stratum: 0 (unspecified) # The peer name is BLANK and the state is Pending. NtpClient is enabled and # configured for NT5DS, but it never resolved a domain controller to talk to. # A count of 1 peer looks reassuring in a monitoring script. Read the name.

Every line in [Configuration] is annotated (Local), meaning registry defaults rather than Group Policy - confirmed independently, since HKLM\SOFTWARE\Policies\Microsoft\W32Time does not exist on this device. Microsoft notes the corollary: if you set NtpServer by Group Policy on a domain member, "W32Time doesn't use the NtpServer registry value", so w32tm /query /configuration is the only honest view of effective settings. And #Peers: 1 is the kind of thing an inventory script gets wrong - technically true, but the peer has no name, no mode and no stratum, and its state is Pending.

Step 4: the registry values worth knowing by name

All of the following live under one root. The subkey is shown in the value column.

HKLM\SYSTEM\CurrentControlSet\Services\W32Time
ValueMeaningWhat to look for
Parameters\TypeWhich sources to accept: NoSync, NTP, NT5DS, AllSync. Default NT5DS on domain members, NTP stand-alone.NTP on a domain member means somebody pointed it at a manual peer. NoSync on an endpoint means nothing will ever correct it.
Parameters\NtpServerPeer list with per-peer flags: 0x1 SpecialInterval, 0x2 UseAsFallbackOnly, 0x4 SymmetricActive, 0x8 Client.Measured time.windows.com,0x9 - 0x8 plus 0x1, so Client mode on the special poll interval. Present but unused, because Type is NT5DS.
Config\MaxAllowedPhaseOffsetLargest offset in seconds W32Time fixes by slewing the clock rate. Above it, the clock is set directly. Default 300 for domain members, 1 stand-alone.Measured 300. A domain member slews away up to five minutes of error gradually, which is why a bad clock can take a long time to visibly converge.
Config\MaxPosPhaseCorrection / MaxNegPhaseCorrectionLargest correction the service will make. "If the service determines that a change larger than this value is required, it logs an event instead." 0xFFFFFFFF means always correct.Measured 4294967295 on both - the domain-member default. DCs default to 172,800 (48 hours), stand-alone to 54,000 (15 hours). A DC refusing a sample writes TOO BIG to the W32Time private log.
Config\EventLogFlagsWhich events W32Time writes: 0x1 time jump, 0x2 source change. Default 2.Measured 2. Source changes are logged, bare time jumps are not - so a device that jumps without changing source is quiet in the System log.
TimeProviders\NtpClient\SpecialPollIntervalPoll interval in seconds for manual peers when the 0x1 flag is set. Default 3,600 on domain members, 604,800 stand-alone.Measured 3600. On stand-alone machines the seven-day default is why a workgroup device drifts for a week between polls.
Config\UtilizeSslTimeDataSecure time seeding - use SSL timestamps to seed a grossly inaccurate clock. Default 1, except Windows Server 2025 where it is 0.Measured 1. A backstop against an absurd clock, no help against minutes of drift.
Parameters\ServiceDllThe DLL that implements the service.Measured C:\WINDOWS\system32\w32time.dll, ServiceMain of SvchostEntry_W32Time. Svchost-hosted, so there is no w32time.exe in Task Manager.

Step 5: read the Time-Service log, both halves of it

There are two places Windows writes time-service events and practitioners routinely check only one. The System log carries the classic warnings under the provider Microsoft-Windows-Time-Service. Separately, Microsoft added a traceability channel in Windows 10 1703 and Windows Server 2016 1709 that is "enabled by default and can be found in the event viewer under the Applications and Services Log\Microsoft\Windows\Time-Service\Operational channel".

PowerShell - read both Time-Service surfaces (read-only)
Get-WinEvent -FilterHashtable @{LogName='System'; ProviderName='Microsoft-Windows-Time-Service'} -MaxEvents 15 | Select-Object TimeCreated, Id, LevelDisplayName, Message # Real entries from the lab device, abridged. 2026-08-23 10:26:55 129 Warning NtpClient was unable to set a domain peer to use as a time source because of discovery error. NtpClient will try again in 15 minutes and double the reattempt interval thereafter. The error was: The entry is not found. (0x800706E1) 2026-08-23 10:26:55 158 Information The time provider 'VMICTimeProvider' has indicated that the current hardware and operating environment is not supported and has stopped. This behavior is expected for VMICTimeProvider on non-HyperV-guest environments. # Event 129 appeared three times inside a minute, and again the day before. # "15 minutes and double thereafter" is ResolvePeerBackoffMinutes=15 and # ResolvePeerBackoffMaxTimes=7 - both measured at their documented defaults. # After seven doublings the device stops trying often enough to matter.

Event 129 answers "why is the source Local CMOS Clock". The device is configured for the domain hierarchy, tried to find a domain controller to take time from, and failed at discovery. The back-off text is not decoration: it maps onto two registry values you can read, and it explains why the device will not recover on its own within a working day.

Gotcha: Event 158 about VMICTimeProvider looks alarming and is not. C:\Windows\System32\vmictimeprovider.dll - file description "Virtual Machine Integration Component Time Sync Provider Library" - ships on every install and is registered as an enabled input provider whether or not the machine is a Hyper-V guest. On the physical laptop used here it is registered, it starts, it discovers it has no hypervisor to talk to, and it stops. The event says so itself: "This behavior is expected for VMICTimeProvider on non-HyperV-guest environments." Chasing it wastes an hour. Chase the opposite case, covered below, where the provider works and fights the domain.

Now the traceability channel. Microsoft publishes what each of these events is for, which makes them unusually easy to use as a timeline. The table below pairs the documented meaning with the count observed on the lab device.

Applications and Services Logs\Microsoft\Windows\Time-Service\Operational
Event IDMessage / documented purposeWhat it tells you
257Service Start. "W32time service has started at <UTC timestamp>, System Tick Count <n>." Logs configuration, providers, clock rate. Not throttled.Observed 30 times. Each is a boot or service restart - use it to bracket everything else.
258Service Stop. "W32time service is stopping at <UTC timestamp>." Not throttled.Pairs with 257. A 257 with no preceding 258 means the service died rather than stopped.
259NTP Client Provider Periodic Status - current source list and chosen reference server. Throttled to once every 8 hours.Observed 36 times, and here the source list and the chosen reference are both blank. A periodic status naming nothing is the failure, printed every eight hours for anyone who looked.
260Time service configuration and status - the log equivalent of w32tm /query /configuration /verbose. Throttled to once every 8 hours.Observed 33 times. Your archive: it proves what the configuration was last Tuesday without a screenshot.
261System Time is set - on each use of the SetSystemTime API. Not throttled, and documented as deliberately ignoring TimeJumpAuditOffset.Observed 23 times. Proves a jump happened and how big it was. Here the deltas are sub-millisecond - churn, not a jump.
262System clock frequency adjusted. Throttled by TimeAdjustmentAuditThreshold - minimum 128 ppm, default 800 ppm.Observed 23 times, one a -4079.2 ppm correction moving the nominal clock rate from 156250 to 156887. Four thousand ppm is clock discipline working hard.
263Change in the time service settings or the list of loaded providers. Not throttled.Observed 173 times - the most frequent by far. Each is a settings re-read, which Microsoft warns "can affect the overall accuracy of the time synchronization".
264Change in the time sources used by NtpClient - fires on peer state transitions such as Pending to Sync, or Sync to unreachable. Throttled to once every 5 minutes.Observed 25 times. Names the domain controller actually chosen, with the socket pair - the best record of "was this device ever synchronised, and to what".
265Time service source or stratum number changes. Not throttled. Documented as critical for tracking state changes in an NTP topology.Observed 24 times, reporting reference ID and new local stratum. A device that never emits 265 has no source at all.
266Time resynchronisation requested - on network change, resume from standby, a long gap since the last sync, or an admin resync. Throttled to once every 5 minutes.Observed 30 times, with a reason code in the body: 0 admin request, 1 power state change, 2 network interface change. Reason 2 constantly on a desktop is a NIC problem.
272Leap second configuration. Observed but not in Microsoft's published traceability table, which documents 257 to 266.Observed 203 times, the highest count in the log. Do not build alerting that assumes the published list is complete.

Step 6: if it is a domain, check the whole domain

One device eleven minutes out is a device problem. Every device in a site eleven minutes out is a hierarchy problem, and you find that with w32tm /monitor. Microsoft documents it as monitoring W32Time across a domain, with /domain: to pick the domain, /computers: for an explicit comma-separated list where a name prefixed with * is treated as a PDC, and /threads: to set concurrency - default 3, range 1 to 50. Run it before you touch a single endpoint. If the domain controllers disagree with each other, fixing one laptop achieves nothing.

The fix: repair the time source, not the update stack

The fix follows from which of the two questions failed.

If the offset is large but the service is healthy - a named source, a populated last-sync time, a sane stratum - the source itself is wrong or the device has just come back from a long sleep. Force a resynchronisation. Microsoft's Kerberos guidance gives the exact form, including the flag that matters:

w32tm /resync /computer:<Target> /rediscover

/rediscover is documented as redetecting the network configuration, rediscovering network sources and then resynchronising. Plain /resync reuses the source the device already believes in, which is useless when the source is the problem. There is also /nowait if you do not want to block, and /soft, which Microsoft describes as resynchronising using existing error statistics and retained purely for compatibility - not the option you want in a diagnosis.

If the service never synchronised at all, as on the lab device, a resync fails the same way it has been failing. The fault is upstream and there are three usual causes.

  1. Domain controller discovery. Event 129 is a locator failure, not a time failure. Confirm the device can find a DC at all before blaming the clock - Windows Update triage and DC-locator triage are now the same ticket.
  2. UDP 123 blocked. W32Time follows the NTP specification, which "requires the use of User Datagram Protocol (UDP) port 123 for all time synchronization". The Kerberos port list states it as W32Time on the client's ephemeral range to server port 123 UDP. Split-tunnel VPN profiles and host firewalls break this more often than anyone expects.
  3. A device set to NT5DS with nowhere to fall back to. This is the structural problem behind the lab device's state: NT5DS has no documented fallback, so a discovery failure means the CMOS clock wins. AllSync is the documented behaviour you probably wanted - fall back to NtpServer when the domain hierarchy is unavailable.
Watch out: do not "fix" a domain member by pointing it at an internet NTP server and walking away. Microsoft is explicit about the consequence: "if a computer synchronizes with a manually specified source rather than its authenticating domain controller, the two computers might be out of synchronization, causing Kerberos authentication to fail." You will trade a clock that is wrong for a clock that is right and still cannot authenticate. And because manually specified sources "are not authenticated unless a specific time provider is written for them", you also give up the Kerberos-signed NTP that a domain member gets for free. Fix DC discovery, or set AllSync so the manual peer is a fallback rather than a replacement.

If the machine is a virtual machine, look for two clocks fighting. A virtualised domain controller on a Hyper-V host can be taking time from the host through the Time Synchronization integration service and from the domain hierarchy through W32Time. Microsoft's article on Windows Time Service event IDs 24, 29 and 38 names the mechanism directly: "If domain controllers synchronize time from their own source and synchronize time from the host, the domain controller time can change frequently." The debug log line that gives it away is "The time service is now synchronizing the system time with the time source VM IC Time Synchronization provider."

The documented resolution is to disable time synchronisation on the host - Hyper-V Manager, Settings, Integration services, clear Time Synchronization - and let the guest use domain hierarchy synchronisation. The stakes on a DC are high: Microsoft lists lingering objects left in caches and replication stopping, because "many domain controller tasks are tied to the system time".

Only after the clock has a source do you go back to Windows Update. That ordering is the entire point. And when you do return, be careful which log you reach for. C:\Windows\WindowsUpdate.log on a modern build is a small stub pointing at Get-WindowsUpdateLog; the real traces are ETW .etl files under C:\Windows\Logs\WindowsUpdate. Microsoft's own 0x80072f8f article points at that folder and offers a nice cross-check for this investigation: you can "quickly verify clock accuracy from WindowsUpdate.log that always prints traces in local time".

Tip: do not make Get-WindowsUpdateLog -ForceFlush your first command. It stops the Update Orchestrator and Windows Update services to flush the trace buffers, which perturbs the very thing you are measuring. Read the Time-Service log and the WindowsUpdateClient Operational log first - those cost nothing - and convert ETW traces only when you need transport-level detail.

Proof it worked: a real strip chart and a named reference source

A fix is proven when the service names a source and the offset collapses. Both are visible in the Operational channel, and the lab device holds real examples of the healthy state from earlier in its history - which is how you know the difference is the network, not the build.

Event Viewer - Time-Service/Operational, healthy transition (real, names redacted)
Event ID 264 NTP Client observed a change peer reachability. Ntp Client is now receiving time data from the following NTP Servers: DC-NAME.domain (ntp.d|0.0.0.0:123->DC-IP:123); System Tick Count: 85609. Event ID 265 The time service is now synchronizing the system time with the reference time source DC-NAME.domain (ntp.d|0.0.0.0:123->DC-IP:123) with reference id 0x64400101. Current local stratum number is 6, System Tick Count: 85609. # This is what "fixed" looks like. 264 says a peer transitioned to reachable. # 265 says the service adopted it and took a stratum from it. # ntp.d marks a domain-hierarchy peer. A manual peer shows as ntp.m instead - # which is how you spot a device that was quietly repointed at a manual server.

That ntp.d versus ntp.m distinction is worth committing to memory. Microsoft's documented example of event 259 renders manual peers as ntp.m|0x8|[::]:123->[IPAddress]:123; domain-hierarchy peers on the lab device render as ntp.d. One character in an event message tells you whether a device is following your design or somebody's fix from 2022.

The confirmation sequence, in order:

  1. w32tm /query /source returns a domain controller name, not Local CMOS Clock.
  2. w32tm /query /status shows Leap Indicator: 0, a non-zero stratum, a real Last Successful Sync Time, and Last Sync Error of 0.
  3. w32tm /query /peers shows a peer with a name and an active state, rather than a blank entry stuck in Pending.
  4. A fresh w32tm /stripchart against the same reference shows the offset collapsed, now comparable to the round-trip delay rather than orders of magnitude larger.
  5. Only then re-run the update scan and look for Microsoft-Windows-WindowsUpdateClient/Operational Event 26 ("Windows Update successfully found N updates") and Event 41 ("An update was downloaded").
Context: step 5 needs one caveat from the same fleet. Event 26 reporting "found 0 updates" is not proof of health - a fully patched device and a device excluded by a stale servicing pin emit an identical line. The lab device is a live example: policy pins TargetReleaseVersionInfo to 24H2 while the installed release is 25H2, because the 25H2 enablement package moved it past its own pin. Use Event 26 to prove the transport recovered, and something else to prove the device is compliant.

The binaries involved, and where they actually live

Time diagnostics get written by people who assume there is a w32time.exe. There is not. Here is what is really on disk, measured on the lab device.

FileLocation and identityRole
w32time.dllC:\Windows\System32. 745,472 bytes, file version 10.0.26100.1, description "Windows Time Service".The service itself. Registered as ServiceDll with ServiceMain of SvchostEntry_W32Time, so it runs inside svchost. It is also the DllName for both the NtpClient and NtpServer providers - one DLL, three roles.
w32tm.exeC:\Windows\System32. 274,432 bytes, description "Windows Time Service Diagnostic Tool". Its internal name is w32time.dll.Every command in this article. Microsoft calls it "the preferred command-line tool for configuring, monitoring, and troubleshooting W32Time", and notes local Administrators membership for local use, Domain Admins for remote.
vmictimeprovider.dllC:\Windows\System32. Version 10.0.26100.8972, description "Virtual Machine Integration Component Time Sync Provider Library".The hypervisor time provider. Registered under TimeProviders\VMICTimeProvider as Enabled=1, InputProvider=1 even on physical hardware, where it starts, finds no host and stops with Event 158.
crypt32.dllC:\Windows\System32. Description "Crypto API32".Exports CertVerifyTimeValidity, which compares a certificate's NotBefore and NotAfter against a time you supply - or against the current clock if you supply none. This is where the clock becomes a trust decision.
wuaueng.dllC:\Windows\System32. Version 1509.2607.1012.0, description "Windows Update Agent".The update agent, versioned separately from the OS - 1509.2607.1012.0 on an OS build of 10.0.26200.9168. Agent behaviour can change without the build changing, so "same build" is not "same agent".

The cheap version of all of this is three commands and two logs. w32tm /stripchart for the number, w32tm /query /source and /status for the ownership, then the System log for Event 129 and the Operational channel for 259, 264 and 265. That is a two-minute check, it changes nothing, and it belongs at the front of every Windows Update triage - because the failure it catches is the one whose error message will never point you at it.

References

Was this post helpful?
React below — no account needed
Share this post
LinkedIn X / Twitter Reddit Bluesky

More from EndpointWeekly

Windows Update
Which Update Service Is This Device Actually Registered Against?…
Before troubleshooting why a device gets the wrong updates, enumerate the registered…
Windows Update
The Windows patching triage decision tree: which log, which key,…
Route each patching symptom to the one evidence source that answers it. Then learn the…
Windows Update
One read-only PowerShell collector for Windows patching failures…
Test-Path and value checks return confidently wrong patching verdicts on real devices.…