Configure systemd-timesyncd safely with a drop-in

A box with the wrong NTP servers drifts for weeks before anyone notices, so configure systemd-timesyncd through a proper admin-owned drop-in. This checks the merged result and confirms which server is actually being used. Allow about ten minutes. You need a system using systemd-timesyncd and a root shell for creating the configuration file and restarting the service.

This guide describes the installed Ubuntu package systemd-timesyncd 255.4-1ubuntu8.17, which provides systemd 255. The exact fallback servers are distribution-specific, so inspect your host rather than copying somebody else's list.

1. Inspect the current state

Start without changing anything. These commands are unprivileged and show the effective time-sync state and the configuration files systemd can see:

$ timedatectl show-timesync --all
$ systemd-analyze cat-config systemd/timesyncd.conf

The first command reports fields such as SystemNTPServers, FallbackNTPServers, ServerName, RootDistanceMaxUSec and the poll interval. The second command prints the main configuration followed by applicable drop-ins. Its output is the useful baseline for checking what your change actually merged.

Checkpoint: Record the current server name and the current values before editing. If the service is already synchronised and you only need to change servers, leave the other settings at their defaults.

2. Create one local drop-in

Use a file in /etc/systemd/timesyncd.conf.d/. Files there are administrator-owned and take precedence over vendor configuration. The names are sorted lexicographically, so a two-digit prefix makes ordering obvious. This example sets explicit NTP servers and a fallback list:

$ sudo install -d -m 0755 /etc/systemd/timesyncd.conf.d
$ sudoedit /etc/systemd/timesyncd.conf.d/50-local-time.conf

Put this in the editor, replacing the example names with servers approved for your network:

[Time]
NTP=ntp1.example.net ntp2.example.net
FallbackNTP=pool.ntp.org
RootDistanceMaxSec=5s
PollIntervalMinSec=32s
PollIntervalMaxSec=2048s
ConnectionRetrySec=30s
SaveIntervalSec=60s

Use host names or IP addresses separated by spaces. NTP= is the primary system list. Per-interface servers supplied by systemd-networkd can also participate, and they take precedence over FallbackNTP=. The fallback list matters only when no other NTP server information is available.

Do not add settings just because they exist. In this release the defaults are 5 seconds for root distance, 32 seconds for the minimum poll interval, 2048 seconds for the maximum poll interval, 30 seconds for retrying a new server, and 60 seconds for saving time. The minimum poll interval cannot be below 16 seconds, and the maximum must be greater than the minimum. Time values accept units; spelling them explicitly makes reviews easier.

Safety warning: Changing NTP servers changes where the machine sends time queries. Use servers you trust and consider DNS, firewall and privacy policy before applying a public or third-party pool. Do not use sudo for the inspection commands, but do use it for the directory and file changes above.

3. Validate the merged configuration

Ask systemd to display the result and check the new file's ownership and mode:

$ systemd-analyze cat-config systemd/timesyncd.conf
$ sudo stat -c '%A %U:%G %n' /etc/systemd/timesyncd.conf.d/50-local-time.conf

Look for your [Time] entries in the output. For a single-value option, the last assignment in sorted order wins. List-valued options are collected as files are processed. An empty assignment such as NTP= resets earlier assignments, so do not use it casually in a later file.

Do not edit a vendor file under /usr/lib/systemd. If a package drop-in must be disabled, the documented mechanism is an administrator-owned symlink with the same name under /etc/systemd/timesyncd.conf.d/ pointing to /dev/null. That is a separate, deliberate override and should be recorded for the next administrator.

4. Apply the change and check synchronisation

Restarting the service briefly interrupts its time-sync process, so do this during a suitable maintenance window:

$ sudo systemctl restart systemd-timesyncd
$ systemctl is-active systemd-timesyncd
active
$ timedatectl show-timesync --all

The final command should show your selected server as ServerName once a server has been chosen. The exact address and timestamps vary. A service that is active can still be waiting for a reachable server, so also check the journal if the server field is empty or the clock is not synchronised:

$ journalctl -u systemd-timesyncd --since '-10 minutes' --no-pager

Do not treat an active service as proof that the time is correct. Check the synchronisation state with timedatectl status and verify that UDP port 123 is permitted by the network path. A server name in the configuration is not evidence that DNS resolution, routing or NTP replies work.

5. Undo the change if needed

The drop-in is easy to roll back. First preserve it if you may need to diagnose the change, then move it out of the configuration directory and restart the service:

$ sudo mv /etc/systemd/timesyncd.conf.d/50-local-time.conf /etc/systemd/timesyncd.conf.d/50-local-time.conf.disabled
$ sudo systemctl restart systemd-timesyncd
$ timedatectl show-timesync --all

The .disabled suffix means systemd will not load it as a drop-in. Restore the original name to reapply it. If the file contains a typo or an invalid interval, the service may refuse to start or ignore the setting; inspect systemctl status systemd-timesyncd and the journal before making another edit.

Done means