0X0000233A

DNS_ERROR_RCODE_BADTIME (0X0000233A) – DNS Signature Expired

Network & Connectivity Intermediate 👁 1 views 📅 May 27, 2026

Your DNS server's clock is wrong, so the DNSSEC signature looks expired. Fix: sync time with NTP, then flush DNS cache.

This error means your DNS server's clock is lying to the DNSSEC validator

If you're seeing 0X0000233A (DNS_ERROR_RCODE_BADTIME), the resolver is rejecting a DNSSEC-signed response because the signature's validity window doesn't overlap with the current time as seen by the server. It's almost never a corrupted DNS record — it's a time sync problem. Let's fix it.

The fix: sync your server's clock with a reliable NTP source

What's actually happening here is that DNSSEC signatures have a strict inception and expiration timestamp. If your server's clock is more than a few minutes off (common with VMs that were snapshotted weeks ago), the resolver sees the signature as either not yet valid or already expired.

  1. Check the current system time and time zone. Run this in an elevated command prompt:
    w32tm /query /status
    If the Source says Local CMOS Clock or Free-running, you're not syncing to NTP.
  2. Force an immediate sync to a reliable pool:
    w32tm /config /manualpeerlist:pool.ntp.org /syncfromflags:manual /reliable:yes /update
    w32tm /resync
    On a domain controller, you might need to point to the domain hierarchy instead: w32tm /resync /rediscover.
  3. Verify the sync worked:
    w32tm /query /status /verbose
    Look for Last Successful Sync Time and Phase Offset — offset should be under 100 milliseconds.
  4. Flush the DNS cache on the resolver (client or forwarder):
    ipconfig /flushdns
    dnscmd /clearcache
    If you're using Windows Server, also run Clear-DnsServerCache in PowerShell.
  5. Test the query again:
    nslookup -type=soa example.com 127.0.0.1
    If the error was coming from an authoritative server, run dcdiag /test:dns /v to confirm all zones pass validation.

Real-world trigger: I've seen this most often on Amazon EC2 Windows instances that were stopped for 3+ weeks and restarted without updating the clock. The instance's CMOS drifted 22 minutes. After NTP sync, the error vanished instantly.

Why step 3 (flush cache) is mandatory

The reason step 3 works is that the resolver caches the entire DNSSEC chain, including the negative validation result. Even after you fix the clock, the old signature failure sits in the cache with a TTL that might be minutes or hours. Flushing clears that poisoned entry. Without the flush, you'll keep seeing the error even though the root cause is resolved.

Less common variations of the same issue

Variation A: The server time is correct, but the DNSSEC signing key was rotated

If your domain's zone signing key (ZSK) or key signing key (KSK) was rolled over, but the RRSIG records haven't been updated on the authoritative server, the signature's inception date is in the future. This is a misconfiguration on the DNS provider side. Check with dig +dnssec example.com SOA and look at the RRSIG validity times. If the inception timestamp is after now, the provider needs to re-sign the zone.

Variation B: The resolver's clock is correct, but the authoritative server's clock is wrong

Less common, but happens. The authoritative server's signature says it expired 3 days ago because that server's clock was 72 hours ahead when it signed the zone. In this case, fixing the authoritative server's NTP sync and re-signing the zone is the only path. You can't fix this from the client side — you must contact the domain owner.

Variation C: Virtual machine time drift after snapshot restore

Hyper-V, VMware, and KVM snapshots often restore the VM to the exact time of the snapshot. If the snapshot is 6 months old, the DNSSEC signatures issued after that date won't validate. The fix is identical (NTP sync + cache flush), but you also need to disable and re-enable the time synchronization service in the hypervisor: Set-VM -VMName DNS01 -TimeSyncEnabled $false then $true in PowerShell for Hyper-V.

Prevention: lock down time sync permanently

The real fix is to never let the clock drift again. Do this:

  • For standalone servers: Set the NTP service to start automatically and use a reliable pool:
    w32tm /config /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:manual /reliable:yes /update
    sc config w32time start=auto
  • For domain-joined servers: The domain hierarchy handles this. Verify with w32tm /query /configuration — look for Type showing NT5DS (domain sync) or NTP. If it says NoSync, fix it with Group Policy: Computer Configuration > Administrative Templates > System > Windows Time Service > Global Configuration Settings.
  • In cloud environments (AWS, Azure, GCP): Enable the platform's time sync agent. For AWS, install the Amazon Time Sync service on the instance. For Azure, the Host Time Sync is on by default for Windows — verify with w32tm /query /status — the source should be something like time.windows.com or 169.254.169.123.
  • Monitor drift: Set a scheduled task that runs w32tm /resync daily at 3 AM. Log the output. If you see consistent drift over 5 seconds, investigate the NTP source.

One more thing: If you're running Windows Server 2016 or later, the time service uses NTP client by default, but it honors the MaxNegPhaseCorrection and MaxPosPhaseCorrection registry values (default 172800 seconds = 48 hours). That means if the clock is off by more than 48 hours, w32tm /resync will silently refuse to sync. You'll see no error, but the clock stays wrong. In that case, temporarily set a very large correction window:

reg add HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config /v MaxNegPhaseCorrection /t REG_DWORD /d 0xFFFFFFFF /f
reg add HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config /v MaxPosPhaseCorrection /t REG_DWORD /d 0xFFFFFFFF /f
w32tm /resync
# Then set them back to the defaults
reg add HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config /v MaxNegPhaseCorrection /t REG_DWORD /d 0x2A300 /f
reg add HKLM\SYSTEM\CurrentControlSet\Services\W32Time\Config /v MaxPosPhaseCorrection /t REG_DWORD /d 0x2A300 /f

That's the whole playbook. Fix the clock, flush the cache, lock down NTP. You won't see 0X0000233A again unless someone re-signs a zone with a wrong timestamp or restores a snapshot from 2019.

Was this solution helpful?