WSL2 clock goes out of sync after resuming from sleep/hibernate.
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.
WSL2 clock goes out of sync after resuming from sleep/hibernate.
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.
UPDATE: as mentioned by drkvogel, the Clock Sync fix was released in WSL2 kernel version 5.10.16.3, however, you should install the Windows Store version of WSL:
# powershell install by id
winget install 9P9TQF7MRM4R
# powershell install by name
winget install 'Windows Subsystem for Linux'
At time of writing, this GitHub Issue was open for the bug.
The workaround I chose for my situation (single distro in WSL2) is to use Windows Task Scheduler to run hwclock
in WSL
whenever Windows resyncs hardware clock.
Windows: Open PowerShell as Administrator
schtasks /create /tn WSLClockSync /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
Set-ScheduledTask WSLClockSync -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)
WSL2: Run
sudo visudo
and addhwclock
to sudoers to skip password prompt
# bottom of my file looks like this
...
...
#includedir /etc/sudoers.d
<username> ALL=(ALL) NOPASSWD:/usr/sbin/hwclock, /usr/bin/apt update, /usr/bin/apt upgrade
Results
See image for how to get Event XPath from Windows Event filtering. Use as provided to let task scheduler auto-display scheduled triggers.
Here is a batch script that does this process automatically, for each registered distro:
@echo off
rem this is a programmatic reminder of how to set up wsl clock sync
rem to prevent clock drift after sleep etc
rem see https://mcmap.net/q/75528/-wsl2-rest-api-error-due-to-wsl2-clock-out-of-sync-with-windows-clock-closed and https://github.com/microsoft/WSL/issues/5324
set WSL_UTF8=1
setlocal EnableDelayedExpansion
for /F "tokens=* delims=" %%D in ('wsl --list --quiet') DO (
set hwclock_count=0
for /f "tokens=* delims=" %%C in ('wsl -d %%D bash -c "grep -c hwclock /etc/sudoers.d/hwclock 2>/dev/null"') DO set hwclock_count=%%C
if !hwclock_count! neq 1 (
echo Setting up sudo permissions for hwclock on distro %%D - will prompt for password...
wsl -d %%D sudo bash -c "echo -e '\x25adm ALL=(ALL) NOPASSWD:/usr/sbin/hwclock -s' > /etc/sudoers.d/hwclock"
) else echo hwclock permissions already set up with !hwclock_count! - not changing...
echo Testing resetting the clock - shouldn't prompt for password...
wsl -d %%D sudo /usr/sbin/hwclock -s
set syncname="WSLClockSync%%D"
echo Creating scheduled task %syncname%...
schtasks /create /f /tn "%syncname%" /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
echo Scheduling %syncname% to run even when on batteries...
powershell -command "& {Set-ScheduledTask %syncname% -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)}"
echo Done!
)
/sbin/hwclock
–
Thorium 5.10.102.1-microsoft-standard-WSL2
. –
Bilharziasis 5.10.102.1-microsoft-standard-WSL2
as well. The command sudo hwclock -s
worked though (Ubuntu 20.04) –
Geranial 5.15.90.1
for me. –
Ideal sudo
if you use wsl.exe -u root hwclock -s
–
Finland 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.
hwclock: Cannot access the Hardware Clock via any known method.
. –
Tick hwclock
didn't help. sudo ntpdate ntp.ubuntu.com
worked for me. –
Monosaccharide The fix is now in WSL2 Linux kernel 5.10.16.3
and newer! Note you may need to install WSL2 from the Windows Store to get the latest kernel version per this thread with Craig from Microsoft.
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...
wsl --status
. In my case, I was on an outdated version, and in contrast to my expectations, it was not updated by Windows update regularly, as I had unticked "Receive updates for other Microsoft products" in the Windows update settings in the past. Ticking that box let Windows Update update my WSL and fix the issue. –
Oliphant 5.15.79.1-microsoft-standard-WSL2
, and I still have this problem. wsl --status
shows Default Distribution: Ubuntu-22.04
Default Version: 2
–
Woll Just restart wsl, it works fine for me
wsl --shutdown
then
wsl
in PowerShell
sudo hwclock -s
will sync to Windows, but it's wrong. It actually syncs the date to your hardware clock. Restarting WSL (which is what this answer suggests) syncs to windows, so you can change both Windows and WSL to some fake date easily. Thanks :) –
Biotype UPDATE: as mentioned by drkvogel, the Clock Sync fix was released in WSL2 kernel version 5.10.16.3, however, you should install the Windows Store version of WSL:
# powershell install by id
winget install 9P9TQF7MRM4R
# powershell install by name
winget install 'Windows Subsystem for Linux'
At time of writing, this GitHub Issue was open for the bug.
The workaround I chose for my situation (single distro in WSL2) is to use Windows Task Scheduler to run hwclock
in WSL
whenever Windows resyncs hardware clock.
Windows: Open PowerShell as Administrator
schtasks /create /tn WSLClockSync /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
Set-ScheduledTask WSLClockSync -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)
WSL2: Run
sudo visudo
and addhwclock
to sudoers to skip password prompt
# bottom of my file looks like this
...
...
#includedir /etc/sudoers.d
<username> ALL=(ALL) NOPASSWD:/usr/sbin/hwclock, /usr/bin/apt update, /usr/bin/apt upgrade
Results
See image for how to get Event XPath from Windows Event filtering. Use as provided to let task scheduler auto-display scheduled triggers.
Here is a batch script that does this process automatically, for each registered distro:
@echo off
rem this is a programmatic reminder of how to set up wsl clock sync
rem to prevent clock drift after sleep etc
rem see https://mcmap.net/q/75528/-wsl2-rest-api-error-due-to-wsl2-clock-out-of-sync-with-windows-clock-closed and https://github.com/microsoft/WSL/issues/5324
set WSL_UTF8=1
setlocal EnableDelayedExpansion
for /F "tokens=* delims=" %%D in ('wsl --list --quiet') DO (
set hwclock_count=0
for /f "tokens=* delims=" %%C in ('wsl -d %%D bash -c "grep -c hwclock /etc/sudoers.d/hwclock 2>/dev/null"') DO set hwclock_count=%%C
if !hwclock_count! neq 1 (
echo Setting up sudo permissions for hwclock on distro %%D - will prompt for password...
wsl -d %%D sudo bash -c "echo -e '\x25adm ALL=(ALL) NOPASSWD:/usr/sbin/hwclock -s' > /etc/sudoers.d/hwclock"
) else echo hwclock permissions already set up with !hwclock_count! - not changing...
echo Testing resetting the clock - shouldn't prompt for password...
wsl -d %%D sudo /usr/sbin/hwclock -s
set syncname="WSLClockSync%%D"
echo Creating scheduled task %syncname%...
schtasks /create /f /tn "%syncname%" /tr "wsl.exe sudo hwclock -s" /sc onevent /ec system /mo "*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
echo Scheduling %syncname% to run even when on batteries...
powershell -command "& {Set-ScheduledTask %syncname% -Settings (New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries)}"
echo Done!
)
/sbin/hwclock
–
Thorium 5.10.102.1-microsoft-standard-WSL2
. –
Bilharziasis 5.10.102.1-microsoft-standard-WSL2
as well. The command sudo hwclock -s
worked though (Ubuntu 20.04) –
Geranial 5.15.90.1
for me. –
Ideal sudo
if you use wsl.exe -u root hwclock -s
–
Finland This worked for me on Ubuntu 22.04.2 LTS.
Install ntpdate
sudo apt install ntpdate
Add this line to ~/.profile
sudo ntpdate time.windows.com
Now everytime you open a new session, the date and time get synced. Also if you want to sync for an existing session, run the command :
sudo ntpdate time.windows.com
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
.
* * * * * date > /tmp/log.txt
pgrep cron
.sudo service cron start
.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.
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w32time\Config
, set MaxPollInterval
to hex c
, decimal 12
.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
hwclock -s
did not solve this issue, even though I'm running a recent WSL kernel. My Windows time is fine, but the sync... doesn't, leaving my WSL time more than 30 seconds out of date. I have to rely on ntpdate
instead, since I am calling APIs with very sensitive time requirements (5 seconds...) –
Garek This GitHub Issue was closed
You can also run the below command in Powershell Terminal so sync it.
wsl.exe sudo hwclock -s
sudo
if you use wsl.exe -u root hwclock -s
–
Finland sudo hwclock -s
in your linux terminal. –
Grader I started having this issue about 6-9 months ago. Restarting wsl always works, but that is not ideal for obvious reasons. hwclock -s
running through a cron job at regular intervals worked for a few months, but not anymore. @igor-alex's approach is working for me, but it required some different steps:
/etc/wsl.conf (same as above)
[boot]
systemd=true
Install systemd-timesync (same as above)
sudo apt install systemd-timesyncd
The suggested edits for timesyncd did NOT work for me and resulted in failure to start the service. Instead I did the following:
sudo systemctl edit systemd-timesyncd.service
[Unit]
ConditionVirtualization=
ConditionVirtualization=wsl
Courtesy of https://unix.stackexchange.com/a/737366/547670
And start it (same as above)
sudo systemctl start systemd-timesyncd
HTH
ConditionVirtualization=
line entirely. I'm on Windows 11. –
Unhallowed If that issue still happened on a version higher than 5.10.16.3
(as it was for my version 5.15.90.1
) you could fix it by systemd service
Thirst, make sure that you have systemd enabled, /etc/wsl.conf
has:
[boot]
systemd=true
Then install systemd-timesyncd
:
sudo apt install systemd-timesyncd
Edit timesyncd config:
sudo systemctl edit systemd-timesyncd
with(to make it run inside virtualized environment):
[Unit]
ConditionVirtualization=
And start it:
sudo systemctl start systemd-timesyncd
Thanks for the solution from the github issue
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.
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
For me this issue seems to be happening when the system goes to sleep. So I have registered a bash command to call whenever, it goes out of sync. I did it by adding a function.sh
file and sourced it in ~/.bashrc
.
function.sh
:
YELLOW='\033[0;33m'
NC='\033[0m'
TIME_SERVER=ntp.ubuntu.com
# Sync wsl time
sync_date () {
echo -e "${RED}sudo ntpdate $TIME_SERVER ${NC}"
echo
sudo ntpdate $TIME_SERVER
}
~/.bashrc
:
source ~/Linux/funtions.sh
Note that I have added a bit of color and some customizations (TIME_SERVER: [windows time server is other option]).
You can sync the time using sync_date
command in cli.
If you want to go the route of adding something to the end of your ~/.bashrc
or ~/.profile
, but find it annoying to have to type in your su password all the time, you can create a timed prompt to only run the update when you want. Here I have achieved this by put a wrapper around Haribk's function:
YELLOW='\033[0;33m'
NC='\033[0m'
TIME_SERVER=ntp.ubuntu.com
# Sync wsl time
sync_date () {
# Uncomment one of the options below.
cmd="ntpdate $TIME_SERVER"
#cmd=hwclock -sv
echo -e "${YELLOW}sudo ${cmd}${NC}"
echo
sudo $cmd
}
date
t=10
resp=
while [[ $t != 0 ]]
do
t=$(( $t - 1 ))
read -t1 -ep"($t) Sync clock with host? [yN] " -n1 resp
if [[ $? == 0 && $resp == '' || ${resp,,} == 'n' ]]
then
break
fi
if [[ ${resp,,} == 'y' ]]
then
sync_date
break
fi
done
if [[ $resp == '' ]]; then echo; fi
This gives a “y/n” prompt that counts down from 9, and assumes “n” if nothing is entered in that time or the Enter key is pressed.
Run the following with an Admin PowerShell.
# Schedule a task to set the date inside WSL to the date found by PowerShell.
# It uses "RU" to run as SYSTEM user.
schtasks /Create /F /TN wsl-clock-sync /RU SYSTEM /SC ONEVENT /EC System `
/TR "powershell -command &{wsl -u root date -s `$(date)}" `
/MO "*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and (EventID=107 or EventID=507) or Provider[@Name='Microsoft-Windows-Kernel-General'] and (EventID=1)]]"
Pause
The command it will run as a scheduled task is
wsl -u root date -s $(date)
Update: It doesn't seem to be working...
© 2022 - 2024 — McMap. All rights reserved.