systemd-timesyncd can report success while drifting
timedatectl prints System clock synchronized: yes.
You put that line in a monitoring check, because it is the obvious thing to
check. Months later the machine is four seconds off and the check is still
green.
What the flag actually means
NTPSynchronized is not "the clock is currently correct". It is
a latch: it is set the first time systemd-timesyncd successfully
adjusts the clock after boot, and on a long-running system essentially nothing
clears it. Lose network, lose your upstream server, get filtered on UDP 123 —
the flag stays yes and the clock quietly walks away from truth at
whatever rate the hardware drifts.
This is arguably correct behaviour for what the flag is for, which is telling
units ordered after time-sync.target that the clock has been set
at least once. It is useless as a health signal.
What to check instead
Ask the daemon when it last actually heard from a server, and how far off it thought it was:
timedatectl show-timesync --all
The fields worth reading are ServerName,
PollIntervalUSec, and the NTPMessage block, which
carries the offset from the last exchange. If the poll interval has climbed to
its maximum and the offset is stale, the daemon is backing off because it is
not getting useful answers.
For anything you actually care about, timesyncd is the wrong tool
— it is an SNTP client, it keeps no discipline history, and it will happily
step your clock. Install chrony and check
chronyc tracking, which reports the real quantities:
chronyc tracking | grep -E 'Last offset|RMS offset|Leap status'
Leap status: Normal plus an RMS offset in the low milliseconds is
a health check. Not synchronised is a real alarm, and unlike the
systemd flag it goes back to that state when things break.
The part that bites
A clock that is seconds fast breaks TLS in a way that reads as a certificate problem. A freshly issued certificate is not yet valid according to your machine, and you spend the afternoon inspecting the certificate instead of the clock. The error message never mentions time.