Skip to content

Clock change detected. Flushing caches and stop DNS to work in the WSL #761

Open

Description

@mihalt

Description

Hi! Pay attention to my comment and the issue itself, please microsoft/WSL#13777 (comment)

Reproduce

Expected behavior

No response

docker version

-

docker info

-

Diagnostics ID

Additional Info

No response

Activity

  1. ttk commented on Apr 4, 2026

    @ttk

    Only when docker desktop is running, Clock change detected. Flushing caches message is generated every 30 seconds in the WSL syslog.

    Mar 31 16:06:50 device systemd-resolved[171]: Clock change detected. Flushing caches.
    Mar 31 16:06:21 device systemd-resolved[171]: Clock change detected. Flushing caches.
    Mar 31 16:05:51 device systemd-resolved[171]: Clock change detected. Flushing caches.
    

    Running Ubuntu 24.04 and Docker Desktop 4.67.0.

  2. 0xdhx commented on Jul 17, 2026

    @0xdhx

    Adding the mechanism behind this symptom, traced on an affected box (Docker Desktop 4.77.0, engine 29.5.3; also observed by the reporter above on 4.67.0). Short version: the 30-second clock step is a userspace settimeofday(2) call made by Docker Desktop's own init process (/initd) inside the docker-desktop distro — not WSL's Hyper-V TimeSync path, and not a kernel bug. Because all of a user's WSL2 distros share one utility VM and one CLOCK_REALTIME, the step lands on every co-resident distro, which is why systemd-resolved in an unrelated Ubuntu distro flushes its DNS cache twice a minute.

    1. Causation is reversible (A→B→A)

    Counting clock steps with the same watcher systemd-resolved arms (timerfd + TFD_TIMER_CANCEL_ON_SET), toggling only Docker Desktop:

    Docker Desktop UP     4 steps / 100 s   @ 30.002 s   (2.40/min)
    Docker Desktop DOWN   0 steps / 130 s                (0.00/min)     <- DockerCli.exe -Shutdown
    Docker Desktop UP     3 steps / 100 s   @ 30.001 s   (1.80/min)     <- restarted
    

    2. The transport is a userspace syscall from initd

    bpftrace on the shared WSL2 kernel while the steps fired:

    @host_disciplined_clock: 0      # hv_set_host_time (Hyper-V TimeSync path) — never called
    @settimeofday_by[initd, 2801]: 3
    @stack[
        do_settimeofday64+5
        __x64_sys_settimeofday+135   # <- plain settimeofday(2) from userspace
        x64_sys_call+6775
        do_syscall_64+90
        entry_SYSCALL_64_after_hwframe+120
    ]: 3
    
      [17:49:28] do_settimeofday64  <- comm=initd pid=2801
      [17:49:58] do_settimeofday64  <- comm=initd pid=2801   # exactly 30 s apart
      [17:50:28] do_settimeofday64  <- comm=initd pid=2801
    

    The kernel Hyper-V TimeSync setter (hv_set_host_time, the function that would call do_settimeofday64 on a host-initiated sync) fired zero times — which also explains why hv_utils.timesync_implicit=0 does not help: the steps never enter that code path.

    A follow-up capture joined each call to its argument and effect: five consecutive settimeofday(2) calls from comm=initd, each requesting a backward step (kernel-side capture of the timespec64 argument), each returning 0, each matched 1:1 with a TFD_TIMER_CANCEL_ON_SET cancellation — the per-event delta agreeing to microseconds with an independent realtime-vs-monotonic watcher, and hv_set_host_time again at zero throughout.

    3. initd ships in Docker Desktop's distro, and nowhere else on this box

    In the docker-desktop distro (PRETTY_NAME="Docker Desktop"), PID 1 is init(docker-desktop) and the processes with comm=initd resolve to the /initd binary. No initd exists in the affected Ubuntu distro (its init is systemd; the WSL core init is /init, comm init).

    4. One VM, one clock

    Both distros report the same boot_id and the same uptime — one utility VM, one CLOCK_REALTIME. A step made in the docker-desktop distro is a step in every distro.

    5. Magnitude: ~1 ms

    The steps measure at ~0.2–2.5 ms each (typically ~1.2–1.7 ms), always backward — two independent instruments (kernel-side capture of the requested timespec64 and userspace realtime-vs-monotonic differencing) agree per event to microseconds. These are tiny corrections applied as hard clock steps, every 30 s, for as long as Docker Desktop is running (observed across three days).

    Suggested fix

    Periodic guest-clock correction is legitimate (WSL2 guests genuinely drift across Windows sleep — cf. microsoft/WSL#10006). The problem is stepping rather than slewing:

    1. Slew small deltas via adjtimex (gradual ADJ_OFFSET slewing — not ADJ_SETOFFSET, which is itself a step) instead of settimeofday. A slew is not a CLOCK_REALTIME discontinuity and does not wake TFD_TIMER_CANCEL_ON_SET watchers — no cache flush, no log spam. This is exactly what the systemd maintainer prescribed when the consumer half of this was reported there (resolved: on_clock_change() flushes the entire DNS cache on any CLOCK_REALTIME step, with no magnitude check systemd/systemd#43028, closed not-our-bug: "if wsl makes continious small steps then they really should use the gradual clock changes (adjtimex) instead of the stepping ones (clock_settime)").
    2. Or gate on magnitude: only hard-step when the delta is large enough to matter (post-resume drift is seconds to minutes), and skip or slew when the guest is already within a few ms — as it was in every measurement here.

    Either change stops the flush loop in every co-resident distro while keeping real post-resume corrections (a large step after actual sleep would still step, correctly).

    Reproduction

    # 1. Cadence (no root): arm an absolute CLOCK_REALTIME timerfd (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET) and
    #    count ECANCELED wakeups — steps land every ~30 s while Docker Desktop runs.
    
    # 2. Transport (root, bpftrace):
    sudo bpftrace -e '
      kprobe:hv_set_host_time  { @host_path = count(); }
      kprobe:do_settimeofday64 { @by[comm] = count(); @stk[kstack(5)] = count(); }
      interval:s:95 { exit(); }'
    #    Expect: @host_path absent/0 ; @by[initd] > 0 ; stack through __x64_sys_settimeofday.
    
    # 3. Causation: "DockerCli.exe -Shutdown" -> steps stop; restart Docker Desktop -> steps return.

    Environment: Windows 10 (19045-class) host, WSL2 kernel 6.6.114.1-microsoft-standard-WSL2, Ubuntu 24.04 (systemd 255.4) co-resident with docker-desktop; reproduced 2026-07-14 and re-confirmed 2026-07-16/17 on Docker Desktop 4.77.0.

    Two honest boundaries: (1) I did not disassemble /initd, so I can't say why it re-steps every 30 s rather than on demand — though the joined trace confirms each call writes a fresh backward ~1 ms correction and succeeds — and the fix direction (slew or magnitude-gate) holds regardless. (2) This trace explains the cache-flush loop and the log spam specifically; whether flushing alone accounts for every network symptom reported upstream is for the thread to judge.

    Cross-references: microsoft/WSL#13777 (same symptom, correctly correlated with Docker Desktop by its reporters), systemd/systemd#43028 (the resolved-side half, closed with "report to the stepper").

  3. 0xdhx commented on Sep 18, 2026

    @0xdhx

    Re-confirmed on current Docker Desktop, and adding the intake data this report's fields were left
    blank for.

    Still reproducing on 4.89.0

    Measured today (2026-09-17) with the same instrument as my July capture — an absolute
    CLOCK_REALTIME timerfd armed TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, counting cancellations,
    alongside an independent realtime-vs-monotonic watcher:

    3 CLOCK_REALTIME steps in 100 s
      at t = 13.165, 43.161, 73.167 s
      intervals = 29.996 s, 30.006 s
      offsets   = -1.978 ms, -2.182 ms, -1.427 ms
    

    Unchanged from July in cadence (30.00 s), direction (backward) and magnitude (~1–2 ms), on a Docker
    Desktop two minor versions newer.

    Intake data

    • Diagnostics ID: 01EFED8D-7EBF-4EAA-BB3D-167A7612FBC3/20260918022054
    • docker version:
    Client:
     Version:           29.7.2
     API version:       1.55
     OS/Arch:           linux/amd64
     Context:           default
    Server: Docker Desktop 4.89.0 (238018)
     Engine:
      Version:          29.7.2
      API version:      1.55 (minimum version 1.40)
      OS/Arch:          linux/amd64
     containerd:
      Version:          v2.3.3
     runc:
      Version:          1.4.3
     docker-init:
      Version:          0.19.0
    
    • docker info (relevant lines):
     Server Version: 29.7.2
     Operating System: Docker Desktop
     Kernel Version: 6.6.114.1-microsoft-standard-WSL2
     Name: docker-desktop
    
    • Host: Windows 10, 19045-class. Co-resident distro: Ubuntu 24.04.4 LTS, systemd 255.4.

    Mechanism (unchanged from my earlier comment)

    Full trace in #761 (comment). In short: the
    30-second step is a userspace settimeofday(2) call from Docker Desktop's /initd inside the
    docker-desktop distro, attributed under bpftrace to comm=initd, with hv_set_host_time — the
    Hyper-V TimeSync setter — at zero calls throughout the capture. Because these co-resident distros
    share one utility VM and one CLOCK_REALTIME, the step lands in every distro on the box.

    Because the observed calls are userspace settimeofday rather than the Hyper-V path,
    hv_utils.timesync_implicit=0 does not address this particular mechanism — that parameter governs
    implicit host synchronisation, not userspace callers.

    Suggested fix

    Unchanged: slew small deltas via adjtimex gradual ADJ_OFFSET rather than stepping (note
    ADJ_SETOFFSET is itself a step, so not every adjtimex mode qualifies), or gate the hard step on
    magnitude so a genuine post-resume correction still steps while a ~1 ms one does not. A slew is not a
    CLOCK_REALTIME discontinuity and does not cancel TFD_TIMER_CANCEL_ON_SET watchers.

    For reference, the systemd maintainers closed the consumer-side report (systemd/systemd#43028) as
    not-their-bug, recommending gradual adjustment over stepping. They attributed the stepping to WSL and
    asked for it to be reported there; the attribution to Docker Desktop's /initd is from my later
    trace, not theirs. The magnitude-gating option is my suggestion, not part of their recommendation.

    Scope

    I traced the successful syscalls and their effects; I did not inspect /initd's implementation, so I
    can't say why it re-steps every 30 s rather than on demand. This explains the periodic clock steps
    and the cache-flush messages they cause. It does not establish the cause of every DNS or connectivity
    failure reported in the WSL thread — @mihalt reported DNS problems there that persisted after Docker
    Desktop was removed.

    Happy to supply a bundle, a bpftrace capture, or a test-build result.

  4. tobiasscott-web commented on Oct 19, 2026

    @tobiasscott-web

    Description

    Docker Desktop's init process in the docker-desktop WSL2 distro appears to step the shared WSL2 VM clock backwards roughly every 30 s via settimeofday(). This looks like the same cause as the reports above (4.67.0, 4.77.0, 4.89.0); it is also reproducible on 4.95.0.

    Reported observations (from a trace taken in an Ubuntu 24.04 WSL2 distro with kernel ftrace syscall tracepoints):

    • settimeofday() is called every ~29.97 s, each time by a short-lived "initd" process with a new pid
    • it is the only syscall that steps the clock (no clock_settime in the traced window)
    • recent steps are about -30 ms each (earlier comments in this issue report 1-2.5 ms)
    • each step matches one "Clock change detected. Flushing caches." entry from systemd-resolved, and journald logs "Time jumped backwards"
    • a chronyd process in the init pid namespace calls clock_adjtime about every 8 s (reported, not independently confirmed)
    • the steps stop when Docker Desktop is fully quit and return when it restarts

    Reproduce

    1. Windows 11 with WSL 2.7.11 and Ubuntu 24.04 with systemd enabled
    2. Start Docker Desktop 4.95.0 (WSL2 backend)
    3. In Ubuntu run: journalctl -fu systemd-resolved
    4. Watch "Clock change detected. Flushing caches." appear every ~30 s
    5. Fully quit Docker Desktop and the messages stop

    Expected behavior

    Small clock corrections are slewed (adjtime/adjtimex) instead of stepped, or small offsets are skipped, so other WSL2 distros don't see clock jumps. Alternatively, an option to disable Docker Desktop's own time sync.

    docker version

    Docker Desktop 4.95.0 (build 242831), engine/CLI 29.8.2
    (full docker version output: not provided)

    docker info

    (not provided; redact host-specific details before posting)

    Diagnostics ID

    (add only if the reporter chooses to share it)

    Additional Info

    WSL 2.7.11.0, kernel 6.18.33.2-microsoft-standard-WSL2, Windows 11 build 10.0.26300.9711. Clock offset vs Windows stays under ~0.3 s. Ruled out: Docker Desktop restart, stopping systemd-timesyncd, wsl --shutdown, Windows reboot, fixing w32time, hv_utils.timesync_implicit=0.

  5. hbigot1970 commented on Oct 19, 2026

    @hbigot1970

    Still reproducing on Docker Desktop 4.95.0 (build 242831, engine 29.8.2), WSL 2.7.11, Windows 10.0.26300.9711, Ubuntu 24.04 distro. Also reported to Docker Support, who asked me to bring the data here.

    Symptom (unchanged)

    systemd-resolved in Ubuntu logs Clock change detected. Flushing caches. every 30 s (121 times in the last hour) and drops its whole DNS cache each time. journald logs Time jumped backwards. If you fully quit Docker Desktop, the flushes stop at once. They come back when you start it again.

    New data points vs. the earlier comments here

    Kernel ftrace syscall tracepoints, enabled from the Ubuntu distro (all distros share one kernel, so docker-desktop processes are visible):

    initd-22110 [004] 67179.004188: sys_settimeofday(tv: 0x2c8157c6dc38, tz: 0)
    initd-22374 [004] 67208.975387: sys_settimeofday(tv: 0x2c8156a1fc38, tz: 0)
    initd-22338 [002] 67238.946063: sys_settimeofday(tv: 0x2c8155edfc38, tz: 0)
    
    • Every call comes from a short-lived initd child with a new pid, every 29.97 s, so /initd seems to fork a helper on a 30 s timer. settimeofday is the only syscall that steps the clock (no clock_settime).
    • The steps can be much larger than the 1–2 ms seen here before. I measured −5 to −8 ms on 2026-10-18 and −29 to −32 ms on 2026-10-19 (CLOCK_REALTIME − CLOCK_MONOTONIC sampled every 20 ms).
    • A chronyd (pid 111 in the init pid namespace, not visible from Ubuntu or docker-desktop) calls clock_adjtime every 8 s. The tick wanders between 10000 and 10190 (normal is 10000). That may be why the guest clock keeps drifting between the /initd corrections. Resetting the tick by hand is reverted within seconds.

    Ruled out

    Stopping systemd-timesyncd, restarting Docker Desktop, wsl --shutdown, rebooting Windows, fixing Windows w32time (now synced to an NTP pool), and hv_utils.timesync_implicit=0 on the kernel command line. None of them stopped the 30 s steps. Only quitting Docker Desktop does.

    Suggested fixes

    1. Slew small offsets (adjtime/clock_adjtime with ADJ_OFFSET) instead of stepping with settimeofday.
    2. Only step above a threshold (e.g. > 1 s, like chrony's makestep), which would cover real host sleep/resume.
    3. Or make it configurable / let it be turned off when the WSL system distro already disciplines the clock.

    A Diagnostics ID gathered during the stepping has been shared with Docker Support.

    Full ftrace output (settimeofday / clock_adjtime / adjtimex, 95 s)
    Syscall trace of the clock stepping
    Captured 2026-10-19 ~15:04-15:06 local time (UTC+02:00) on the affected host, while Docker Desktop 4.95.0 was running.
    Method: kernel ftrace syscall tracepoints, enabled from the Ubuntu-24.04 distro (all WSL2 distros share one kernel,
    so this sees processes of docker-desktop and of the WSL system distro too). Events: settimeofday (enter/exit),
    clock_settime, clock_adjtime, adjtimex. Duration 95 s. Timestamps in column 4 are ftrace's local clock (seconds).
    
    == 1. settimeofday calls only ==
               initd-22110   [004] ..... 67179.004188: sys_settimeofday(tv: 0x2c8157c6dc38, tz: 0)
               initd-22110   [004] ..... 67179.004636: sys_settimeofday -> 0x0
               initd-22374   [004] ..... 67208.975387: sys_settimeofday(tv: 0x2c8156a1fc38, tz: 0)
               initd-22374   [004] .N... 67208.975500: sys_settimeofday -> 0x0
               initd-22338   [002] ..... 67238.946063: sys_settimeofday(tv: 0x2c8155edfc38, tz: 0)
               initd-22338   [002] .N... 67238.946177: sys_settimeofday -> 0x0
    
    Notes:
     - each call comes from a short-lived 'initd' process with a NEW pid every time (22110, 22374, 22338):
       /initd seems to fork a helper every ~30 s (intervals between calls: 29.97 s and 29.97 s);
     - no clock_settime calls at all in the window; settimeofday is the only stepping syscall.
     - systemd-timesyncd (pid 498, Ubuntu) reacts ~95 ms after each step with clock_adjtime;
     - a chronyd (pid 111 in the init pid namespace, not visible from Ubuntu or docker-desktop) calls
       clock_adjtime 4-5 times every 8 s - this is likely the tick/freq adjuster mentioned in the report.
    
    == 2. Step size measured right after the trace (CLOCK_REALTIME - CLOCK_MONOTONIC, sampled every 20 ms) ==
    2026-10-19 15:06:31 UTC+0200 step -31.89 ms
    2026-10-19 15:07:01 UTC+0200 step -29.00 ms
    (Today's steps are about -30 ms; on 2026-10-18 they were -5 to -8 ms.)
    
    == 3. systemd-resolved in Ubuntu-24.04 over the same period (one flush per step) ==
    2026-10-19T15:04:01+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:04:31+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:05:01+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:05:31+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:06:01+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:06:31+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    2026-10-19T15:07:01+02:00 host systemd-resolved[320]: Clock change detected. Flushing caches.
    
    == 4. Full raw ftrace output ==
    # tracer: nop
    #
    # entries-in-buffer/entries-written: 58/58   #P:5
    #
    #                                _-----=> irqs-off/BH-disabled
    #                               / _----=> need-resched
    #                              | / _---=> hardirq/softirq
    #                              || / _--=> preempt-depth
    #                              ||| / _-=> migrate-disable
    #                              |||| /     delay
    #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
    #              | |         |   |||||     |         |
             chronyd-111     [003] ..... 67171.502589: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [003] ..... 67171.502657: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [003] ..... 67171.502662: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [003] ..... 67171.502667: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
               initd-22110   [004] ..... 67179.004188: sys_settimeofday(tv: 0x2c8157c6dc38, tz: 0)
               initd-22110   [004] ..... 67179.004636: sys_settimeofday -> 0x0
     systemd-timesyn-498     [003] ..... 67179.098817: sys_clock_adjtime(which_clock: 0, utx: 0x7ffc4ddec660)
             chronyd-111     [003] ..... 67179.529557: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [003] ..... 67179.529568: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [003] ..... 67179.529572: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [003] ..... 67179.529596: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [001] ..... 67187.442904: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c226b0)
             chronyd-111     [001] ..... 67187.550674: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [001] ..... 67187.550684: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [001] ..... 67187.550689: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [001] ..... 67187.550692: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [004] ..... 67195.551907: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [004] ..... 67195.551920: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [004] ..... 67195.551925: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [004] ..... 67195.551930: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [002] ..... 67203.546586: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [002] ..... 67203.546641: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [002] ..... 67203.546646: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [002] ..... 67203.546650: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
               initd-22374   [004] ..... 67208.975387: sys_settimeofday(tv: 0x2c8156a1fc38, tz: 0)
               initd-22374   [004] .N... 67208.975500: sys_settimeofday -> 0x0
     systemd-timesyn-498     [001] ..... 67209.072148: sys_clock_adjtime(which_clock: 0, utx: 0x7ffc4ddec660)
             chronyd-111     [000] ..... 67211.580357: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [000] ..... 67211.580404: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [000] ..... 67211.580409: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [000] ..... 67211.580413: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [000] ..... 67219.595076: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [000] ..... 67219.595087: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [000] ..... 67219.595091: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [000] ..... 67219.595096: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [004] ..... 67227.593858: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [004] ..... 67227.593869: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [004] ..... 67227.593873: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [004] ..... 67227.593877: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [004] ..... 67235.588933: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [004] ..... 67235.588945: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [004] ..... 67235.588949: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [004] ..... 67235.588953: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
               initd-22338   [002] ..... 67238.946063: sys_settimeofday(tv: 0x2c8155edfc38, tz: 0)
               initd-22338   [002] .N... 67238.946177: sys_settimeofday -> 0x0
     systemd-timesyn-498     [003] ..... 67239.041777: sys_clock_adjtime(which_clock: 0, utx: 0x7ffc4ddec660)
             chronyd-111     [002] ..... 67243.629358: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [002] ..... 67243.629369: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [002] ..... 67243.629374: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [002] ..... 67243.629379: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [004] ..... 67251.637413: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [004] ..... 67251.637433: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [004] ..... 67251.637440: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [004] ..... 67251.637446: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
             chronyd-111     [000] ..... 67259.636352: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c225d0)
             chronyd-111     [000] ..... 67259.636363: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22250)
             chronyd-111     [000] ..... 67259.636368: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22260)
             chronyd-111     [000] ..... 67259.636371: sys_clock_adjtime(which_clock: 0, utx: 0x7ffcc5c22350)
    
  6. transferred this issue fromdocker/for-winon Oct 20, 2026
  7. hbigot1970 commented on Oct 21, 2026

    @hbigot1970

    Still reproducing after updating to Docker Desktop 4.96.0 (build 243774, engine 29.9.1, released today), WSL 2.7.11, Windows 10.0.26300.9711, Ubuntu 24.04 distro.

    State on 4.96.0 (measured 2026-10-21, ~10 minutes after the update)

    • systemd-resolved still logs Clock change detected. Flushing caches every 30.0 s (e.g. 17:27:15.692, 17:27:45.692, 17:28:15.689, 17:28:45.684 UTC), right from Docker Desktop's restart, so the DNS cache stays useless in every WSL distro.
    • CLOCK_REALTIME − CLOCK_MONOTONIC sampled every 50 ms for 92 s: one backward step every 30 s, of −8.7 ms, −7.8 ms, −8.5 ms (smaller than the ~−30 ms I saw on 4.95.0 two days ago, but still a step rather than a slew).
    • ftrace of syscall entry tracepoints for 65 s:
      • settimeofday: 2 calls, 29.99 s apart, both from initd (one from a long-lived initd process, one from a short-lived initd child; on 4.95.0 every call came from a new short-lived child);
      • clock_adjtime: 32 calls from chronyd (≈ every 2 s, versus every 8 s on 4.95.0) and 2 from systemd-timesyncd.

    So the update did not change the behaviour: initd still steps the shared clock every 30 s, while chronyd (WSL system distro) now disciplines it more often. Both keep fighting, and every initd step triggers the cache flush in all distros.

    Still suggested

    1. Slew small offsets (clock_adjtime with ADJ_OFFSET) instead of settimeofday.
    2. Or only step above a threshold (e.g. > 1 s), which still covers host sleep/resume.
    3. Or make it configurable / skip it when the WSL system distro's chronyd already disciplines the clock.

    Happy to test a pre-release build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions