'WSL2 Clock is out of sync with Windows

WSL2 clock goes out of sync after resuming from sleep/hibernate. illustration showing Windows clock and WSL clock out of sync

A workaround was shared on GitHub sudo hwclock -s to resync clock in WSL, but you have to do this every time you resume from sleep/hibernate.



Solution 1:[1]

In case anyone finds this via search and doesn't notice that there is actually a solution listed in the question, you can fix WSL clock drift via.

sudo hwclock -s

If you just need to do it occasionally, this is a fine solution. If you need to do it more frequently, consider @piouson's solution

Solution 2:[2]

sudo hwclock -s gets you kind of there, but for some reason doesn't get the exact time - I often find it's a minute or so in the future!

sudo ntpdate pool.ntp.org should get you the correct time.

But this is all because of a bug in the Linux kernel which should be included in a Windows update at some point...

There are a number of hacks referenced in the the GitHub issue which can work around this, mostly, but not always, in my experience...

UPDATE: The fix is now in! In the Windows Insiders build, at least: https://devblogs.microsoft.com/commandline/servicing-the-windows-subsystem-for-linux-wsl-2-linux-kernel/

Solution 3:[3]

just restart wsl, it works fine for me

wsl --shutdown

then

wsl

in PowerShell

Solution 4:[4]

You can manually update the WSL2 kernel to 5.10.16 by following the method in this comment: #5650 (comment). I have fixed the issue by this method.

Solution 5:[5]

Necro'ing this: As of May 2022, this issue persists to a degree.

There are two components.

First, Windows time sync needs to be decent to start with. It's not, out of the box, on machines that aren't domain-joined.

  • Change w32time to start automatically. In Administrator cmd, but not PowerShell, sc triggerinfo w32time start/networkon stop/networkoff. Verify with sc qtriggerinfo w32time. To get into cmd that way, you can start Admin PowerShell and then just type cmd.

  • Make a few changes in regedit.

    • In Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Config, set MaxPollInterval to hex c, decimal 12.
    • Check Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Parameters\NtpServer. If it ends in 0x9 you are done. If it ends in 0x1 you need to adjust SpecialPollInterval in Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\TimeProviders\NtpClient to read 3600
  • Reboot, then from Powershell run w32tm /query /status /verbose to verify that w32time service did start. If it didn't, check triggers again. If all else fails, set it to Automatic Delayed startup

Second, WSL2 needs to actually stay in sync. MS will likely release another kernel fix. In the meantime a scheduled task can bring it back into sync periodically: schtasks /Create /TN WSL2TimeSync /TR "wsl -u root hwclock -s" /SC ONEVENT /EC System /MO "*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and (EventID=107 or EventID=507) or Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]" /F

Solution 6:[6]

I've added this to Windows Task Scheduler, set to run every 12 hours:

wsl.exe -d ubuntu -u root -- ntpdate time.windows.com

To install ntpdate:

sudo apt install ntpdate

Solution 7:[7]

This GitHub Issue was closed

You can also run the below command in Powershell Terminal so sync it.

wsl.exe sudo hwclock -s

Solution 8:[8]

Use cron to schedule sudo hwclock -s

As others said before sudo hwclock -s syncs the clock,
but you will need to do this after every sleep/hibernate. Solution is to add an hourly cron task to sync the clock.

Open crontab with sudo (must open with sudo since the command uses sudo):

sudo crontab -e 

and add this code with a new line after the task (it's a cron requirement):

PATH=/sbin:/bin:/usr/bin
@hourly hwclock -s

You must either set PATH since root-cron do not has it or use absolute paths e.g. /usr/sbin/hwclock.

cron troubleshooting:

  • To verify cron is working you may add a dummy task (don't forget to add a new line):
    * * * * * date > /tmp/log.txt
  • If no file is created, verify cron is working: pgrep cron.
    If no PID shows, start cron with: sudo service cron start.
  • To learn cron timing method: cron timing generator

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Don Alvarez
Solution 2
Solution 3 fahmiduldul
Solution 4
Solution 5 Thorsten Behrens
Solution 6 J. Scott Elblein
Solution 7 M. Kwabena Afreh
Solution 8 Nathan