Can You Mix NTS and Non-NTS Servers in Your Time Synchronization Setup?
No, you cannot mix NTS and non-NTS servers in the same configuration when using the nts-servers repository, as the NTS protocol's TLS authentication layer causes clients to ignore or reject plain NTP responses.
The jauderho/nts-servers repository provides a curated list of NTS-enabled NTP servers designed for secure time synchronization. When configuring time sync clients using the generated files from this repository, you must include only NTS servers to ensure proper authentication and avoid synchronization failures.
Why Mixing NTS and Non-NTS Servers Fails
The Network Time Security (NTS) protocol adds a TLS-based authentication layer on top of standard NTP. When you configure a client to use NTS, it expects encrypted, authenticated time responses. If you attempt to mix NTS and non-NTS servers in the same configuration, one of two outcomes occurs:
- The client ignores or rejects plain NTP responses from non-NTS servers, treating them as untrusted
- The client falls back to insecure NTP, defeating the security purpose of deploying NTS
According to the jauderho/nts-servers source code, the repository enforces an NTS-only policy to prevent these security gaps. The README explicitly states: "It is not possible to mix and match NTP and NTS at this time. Only NTS servers should be specified as the NTP entries will not be used" [README.md L25].
Source Code Evidence
The generated configuration files demonstrate this restriction clearly. In chrony.conf, every server entry includes the nts keyword, which instructs chronyd to require NTS authentication for that peer:
server time.cloudflare.com nts iburst
server 1.ntp.ubuntu.com nts iburst
Similarly, the ntp.toml file for ntpd-rs uses NTS-specific configuration parameters, ensuring the client refuses unauthenticated time data. These files are generated from the canonical nts-sources.yml by scripts/ntpServerConverter.py, which applies the NTS flag uniformly to all entries.
Configuration Examples
Correct NTS-Only Configuration
When using the nts-servers repository, your chrony.conf should contain only servers with the nts flag:
# /etc/chrony.conf (generated by scripts/ntpServerConverter.py)
server time.cloudflare.com nts iburst
server 1.ntp.ubuntu.com nts iburst
server time.example.com nts iburst
This configuration ensures all time sources use encrypted NTS handshakes before transmitting time data.
Incorrect Mixed Configuration
The following configuration will not work as intended because the plain NTP server will be ignored or rejected:
# This configuration is unsupported
server time.cloudflare.com nts iburst # NTS server (OK)
server pool.ntp.org iburst # Plain NTP (will be ignored)
The chronyd daemon will discard responses from pool.ntp.org because they lack the required NTS authentication cookies.
Verifying NTS Server Connectivity
Before deploying, verify individual servers support NTS using the provided validation script:
./scripts/ntsCheck.sh time.cloudflare.com
This script executes a one-shot NTS query via chronyd to confirm the server responds with proper TLS authentication [ntsCheck.sh]. If a server fails this check, it should not be included in your nts-sources.yml or final configuration.
Managing Separate Time Sync Configurations
If your infrastructure requires both NTS-secured time and legacy NTP sources, maintain separate configuration files:
- Use
chrony.conffrom the nts-servers repository for NTS-only clients - Create a distinct
chrony-legacy.conffor systems requiring plain NTP - Run separate chronyd instances or use different client machines
Never combine both server types in the same configuration file when using the nts keyword, as the authentication requirements are mutually exclusive.
Summary
- Mixing is unsupported: The
jauderho/nts-serversrepository explicitly forbids combining NTS and plain NTP servers in the same configuration - Protocol incompatibility: NTS clients reject unauthenticated NTP responses, making mixed configurations ineffective
- Uniform NTS flag: Generated files like
chrony.confandntp.tomlapply thentskeyword to every server entry viascripts/ntpServerConverter.py - Validation required: Use
scripts/ntsCheck.shto verify NTS capability before adding servers tonts-sources.yml - Separate deployments: Maintain distinct configurations if you must support both protocols in your infrastructure
Frequently Asked Questions
What happens if I accidentally mix NTS and non-NTS servers in chrony.conf?
The chronyd daemon will ignore or reject responses from plain NTP servers because they cannot provide the TLS-authenticated NTS handshake required by the nts flag. Your client will synchronize only with the NTS-enabled servers, or potentially fail to sync entirely if no valid NTS servers are reachable.
How do I convert the nts-servers list into a working chrony configuration?
Run the scripts/ntpServerConverter.py script against the nts-sources.yml file. This Python script generates both chrony.conf and ntp.toml with the correct nts keyword applied to every server entry, ensuring compliance with the repository's NTS-only policy.
Can I run both NTS and plain NTP on the same machine?
Yes, but you must use separate configuration files and potentially separate client instances. Do not combine both server types in a single chrony.conf file that uses the nts keyword, as this creates conflicting authentication requirements.
How do I verify that a server truly supports NTS before adding it?
Execute ./scripts/ntsCheck.sh <hostname> to perform a real-time NTS handshake test. The script uses chronyd to attempt authentication and will confirm whether the server provides valid NTS cookies and TLS encryption.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →