Active Directory · Troubleshooting

Kerberos Clock Skew — KRB_AP_ERR_SKEW

KRB_AP_ERR_SKEW means Kerberos has stopped trusting a ticket purely because the clocks on the two machines disagree by more than the domain’s allowed tolerance, and the fix is almost never Active Directory itself — it is whichever clock drifted.

Quick idea: Kerberos tickets carry a timestamp instead of a password on the wire, and that only works as a defence against replay if both sides roughly agree on what time it is. When a client and a domain controller drift more than five minutes apart, the KDC stops trusting the timestamp and returns KRB_AP_ERR_SKEW. Fix the clock, not the directory.
KRB_AP_ERR_SKEW

RFC 4120 error 0x25 — the timestamp in a Kerberos message is outside the accepted clock tolerance.

5-minute tolerance

The default Maximum tolerance for computer clock synchronization Kerberos policy value.

W32Time

The Windows Time service. Nearly every skew incident traces back to this service pointing at the wrong source.

Introduction

A user reports they cannot log on to a workstation that was fine yesterday. Or a scheduled task running under a service account suddenly fails every morning at the same time. Or a newly built VM joins the domain without complaint but nobody can authenticate to it. The common thread: nothing about permissions, passwords, or group membership changed. What changed is time.

Kerberos is deliberately intolerant of clock drift, and that intolerance is a security feature, not a bug. Once you accept that KRB_AP_ERR_SKEW is the protocol doing exactly what it was designed to do, the troubleshooting narrows fast — you are not debugging Active Directory, you are debugging whichever clock stopped following the domain’s time hierarchy.

What You’re Seeing

The error surfaces slightly differently depending on where you look. On the client, the System log records it under the Kerberos source:

# System log, Source: Kerberos, Event ID 4
The kerberos client received a KRB_AP_ERR_SKEW error from the server host/DC01.corp.example.com.
This indicates that the time difference between the client and server is too great.

On the domain controller side, a failed TGT request logs as Event ID 4771 in the Security log, with the failure code that corresponds to the same underlying RFC 4120 error:

# Security log on the DC, Event ID 4771
Status: 0x25
Failure Code: KRB_AP_ERR_SKEW (Clock skew too great)

A logon attempt that fails specifically because of time can also appear as an Event ID 4625 logon failure with sub status 0xC0000133 (STATUS_TIME_DIFFERENCE_AT_DC). Whichever event you land on, the message is the same: authentication was refused on timing grounds alone, not credentials.

Key point: KRB_AP_ERR_SKEW and KRB_AP_ERR_MODIFIED both surface as Event ID 4 from the Kerberos source, and it is easy to mistake one for the other in a quick log scan. MODIFIED means the client could not decrypt the service ticket, most often from a duplicate SPN. SKEW means the timestamp fell outside tolerance. Read the actual event text before choosing a fix.

What It Actually Means

Every Kerberos exchange includes an encrypted timestamp, and the Key Distribution Center on each domain controller checks that timestamp against its own clock before honouring the request. This exists specifically to defeat replay attacks — without a time check, a captured ticket or authenticator could be resubmitted indefinitely. The acceptable difference between a client clock and the domain controller clock is governed by the Maximum tolerance for computer clock synchronization Kerberos policy setting, found at Computer Configuration\Windows Settings\Security Settings\Account Policies\Kerberos Policy in the Default Domain Policy. Its default value is 5 minutes, and Microsoft’s own guidance is to leave it there rather than widen it.

If the gap between the two clocks is inside that window, the timestamp is accepted as authentic and authentication proceeds normally. Cross the threshold in either direction — the client ahead or behind — and the KDC returns KRB_AP_ERR_SKEW. The directory itself, the account, and the password are all untouched by this; the request never gets far enough to check them.

How to Diagnose

Work from cheapest check to deepest. Most skew incidents resolve at the first or second step.

# 1. Compare the affected computer's time against a healthy domain controller
w32tm /stripchart /computer:DC01.corp.example.com /samples:3 /dataonly

# 2. Check what this computer thinks its time source is, and how confident it is
w32tm /query /status /verbose

# 3. Confirm the computer is actually configured to sync from the domain hierarchy
w32tm /query /configuration

# 4. List the peers this computer is currently using
w32tm /query /peers

# 5. Force an immediate resync, rediscovering time sources on the network
w32tm /resync /computer:WORKSTATION01 /rediscover

# 6. Confirm a domain controller is reachable at all - a skew report can
# sometimes be a symptom of a bigger DC-locator problem
nltest /dsgetdc:corp.example.com /force /kdc
Practical note: w32tm /stripchart is the fastest way to prove skew exists before you touch anything else. If the offset it reports is under five minutes, the clocks are not your problem and you should look at SPNs, encryption types, or DNS instead.

Common Causes

Cause How to Confirm Fix
VM paused, snapshotted, or resumed w32tm /stripchart shows a large, sudden offset right after a snapshot restore or host migration. w32tm /resync /rediscover on the affected guest; ensure hypervisor time sync integration isn’t fighting W32Time.
Computer not actually following the domain hierarchy w32tm /query /configuration shows Type: NTP instead of NT5DS, or a manual peer list left over from before the domain join. w32tm /config /syncfromflags:domhier /update, then restart the service.
PDC emulator has no reliable external source The forest root PDC emulator’s own w32tm /query /status shows a stale or unreachable source, and drift shows up domain-wide. Point the PDC emulator at an external NTP source with w32tm /config /manualpeerlist and /reliable:YES.
Drift exceeds 48 hours W32Time’s default MaxPosPhaseCorrection / MaxNegPhaseCorrection on domain controllers is 172,800 seconds (48 hours); beyond that it logs an event instead of correcting. Manually set the clock close to correct first, then let w32tm /resync take over the fine correction.
Firewall blocking UDP 123 or the RPC dynamic range w32tm /stripchart times out or never returns a sample against a partner DC. Allow UDP 123 between the client and its time source, and the dynamic RPC range between DCs.
BIOS/UEFI clock or time zone misconfigured after rebuild Offset is suspiciously close to a whole number of hours (a time zone mismatch) rather than a small drift. Correct the time zone setting; let W32Time handle the rest — do not hand-correct by whole hours.
Non-domain device (appliance, Linux host) with independent clock source The device does not participate in NT5DS at all and is running its own NTP client. Point it at the same time hierarchy — see the Chrony post for the Linux side of this.

Working Through a Fix

Start with the machine reporting the error, not the domain controller. Run w32tm /query /status /verbose and look at the Source and Phase Offset lines — this tells you what the computer believes its time source is and how far off it currently measures itself. If Source is anything other than a domain controller and the machine is domain-joined, the sync chain is broken before you even get to the offset.

# Point the client back at the domain hierarchy explicitly
w32tm /config /syncfromflags:domhier /update

net stop w32time
net start w32time

# Force the resync and confirm the offset has closed
w32tm /resync /rediscover
w32tm /query /status /verbose
Production note: Do not manually set a server’s clock forward or back by hand to “fix” a Kerberos error and walk away. A hand-set clock outside of W32Time’s control drifts again at the next reboot or the next VM pause, and you will be back here within days. Fix the source it is synchronizing from, not the symptom.

If the affected machine is itself a domain controller, check whether it is the PDC emulator for the forest root domain. Every other domain-joined computer eventually chains its time up to that one machine, so if the PDC emulator’s own external time source is stale or unreachable, the drift can appear on unrelated workstations days later with no obvious pattern. The PDC emulator should be the only machine in the environment configured with an external source and /reliable:YES; everything else — including other domain controllers — should inherit from the domain hierarchy (NT5DS), not from an external server directly.

# On the forest root PDC emulator only
w32tm /config /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org" /syncfromflags:manual /reliable:YES /update
net stop w32time && net start w32time

How to Prevent It

Leave the Maximum tolerance for computer clock synchronization policy at its 5-minute default rather than widening it to make an error disappear — the tolerance exists to stop replay attacks, and loosening it trades a real security control for a cosmetic fix. Instead, make sure every domain-joined computer is actually inheriting time from the domain hierarchy rather than a leftover manual configuration from before it joined, and make sure the forest root PDC emulator has a reliable external source configured. On virtualized domain controllers, disable the hypervisor’s own time synchronization integration component so it cannot fight W32Time for control of the clock — this is a frequent source of drift that has nothing to do with Active Directory configuration at all.

Monitor proactively rather than waiting for a help desk ticket: a scheduled w32tm /stripchart or w32tm /monitor /domain:corp.example.com against your domain controllers will surface a drifting PDC emulator before it cascades into workstation-level Kerberos failures. The same time discipline that prevents KRB_AP_ERR_SKEW also underpins the NTP hierarchy your logs, certificates, and replication all depend on.

Quick Reference

Command Use
w32tm /stripchart /computer:<DC> /samples:3 /dataonlyMeasure the offset against a known-good domain controller.
w32tm /query /status /verboseShow current source, phase offset, and sync state.
w32tm /query /configurationConfirm whether the machine is set to NT5DS (domain hierarchy) or a manual/NTP source.
w32tm /resync /rediscoverForce resynchronization and rediscover available time sources.
w32tm /config /syncfromflags:domhier /updateReturn a client to synchronizing from the domain hierarchy.
nltest /dsgetdc:<domain> /force /kdcConfirm a KDC is reachable at all.
Event ID 4 (Kerberos) / Event ID 4771 status 0x25KRB_AP_ERR_SKEW — clock skew exceeded the configured tolerance.

Final Thoughts

KRB_AP_ERR_SKEW looks alarming because it blocks logons outright, but it is one of the more mechanically simple Kerberos failures once you stop looking at the directory and start looking at the clock. The protocol is working correctly — it just refuses to trust a timestamp it cannot verify.

Measure the offset first, trace it back to whichever source stopped following the domain hierarchy, and fix that source rather than the symptom. A domain where every machine inherits time from a well-configured PDC emulator rarely sees this error at all.

Key takeaway: Run w32tm /stripchart /computer:<DC> /samples:3 /dataonly to confirm the offset, then w32tm /query /configuration to check the machine is following NT5DS. Fix the actual time source — most often a PDC emulator with no reliable external reference, or a VM that drifted after a pause — then w32tm /resync /rediscover and re-check the offset before assuming the fix worked.
More troubleshooting

Next: Kerberos authentication failing for a different reason entirely — two identically named service accounts producing KRB_AP_ERR_MODIFIED from a duplicate SPN.