Configure Chrony Time Synchronization in Linux

Tested on RHEL 10.2 (Coughlan)
Package chrony 4.8-2.el10
Applies to RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora, Ubuntu, Debian
Privilege sudo or root
Scope NTP client install, configuration, verification, forced correction, and troubleshooting with chrony and timedatectl. Optional NTP server section for LAN clients is beyond the RHCSA client requirement.
Related guides timedatectl command
Fix VM wrong time after reboot
systemctl command
Open a port in Linux
Check internet connectivity

RHCSA-style time work is client-first: install chronyd, point it at trusted NTP sources, confirm the system clock is synchronized, and know how to step the clock when a VM wakes from suspend with a large offset. This guide follows that order, then covers timezone and hardware clock basics, a troubleshooting matrix, and an optional NTP server section for lab networks.

On RHEL-family systems the service unit is chronyd and the main config file is /etc/chrony.conf. On Ubuntu and Debian the unit is usually chrony and pools may live under /etc/chrony/sources.d/ as well as /etc/chrony/chrony.conf.


How Chrony Time Synchronization Works

Linux keeps two clocks you care about during administration:

  • System clock — what date and timedatectl show; applications read this clock.
  • Hardware clock (RTC) — battery-backed or virtual RTC the kernel reads at boot before NTP adjusts the system clock.

Chrony splits work between a background daemon and a control tool:

Component Role
chronyd Runs continuously, polls NTP sources, slews or steps the system clock, and optionally serves time to other hosts
chronyc Talks to the running chronyd for status, source lists, and one-off actions such as makestep
server / pool lines Upstream NTP peers in chrony.conf (or Ubuntu .sources files)
rtcsync Copies an accurate system clock to the RTC periodically so reboot starts closer to correct time

By default, chronyd corrects clock offsets by slewing — gradually speeding up or slowing down the system clock. Large offsets can therefore take a long time to correct. A configured makestep directive can permit stepping when the offset exceeds its threshold during a limited number of clock updates, and chronyc makestep can request a step manually.

Virtual machines benefit from chrony because hypervisor pauses and snapshot restores can leave the guest clock far from real time. A client with iburst and a sensible makestep line recovers quickly after boot without manual date commands.


Check the Current Date, Time and Timezone

Before you edit NTP sources, read what the system already believes about time and sync state.

timedatectl is the first check on systemd hosts — it shows local time, UTC, RTC, timezone, and whether NTP is active:

bash
timedatectl status
output
Local time: Fri 2026-08-07 21:46:49 IST
           Universal time: Fri 2026-08-07 16:16:49 UTC
                 RTC time: Fri 2026-08-07 16:16:49
                Time zone: Asia/Kolkata (IST, +0530)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no

System clock synchronized: yes means the system considers its clock synchronized. Use chronyc tracking and chronyc sources -v to verify Chrony's actual reference source. NTP service: active means a supported network time service is active; it does not prove that the clock has synchronized with a usable source — as in the sample above.

For a quick wall-clock read without the extra fields, use date:

bash
date
output
Fri Aug  7 09:46:49 PM IST 2026

Timezone changes and deeper timedatectl options live in the timedatectl command cheat sheet. This article focuses on chrony as the NTP client behind timedatectl set-ntp yes.


Install and Manage Chrony

Install the package if it is missing, then enable the service so it starts on boot.

On RHEL, Rocky Linux, AlmaLinux, and CentOS Stream:

bash
sudo dnf install -y chrony

On Ubuntu and Debian:

bash
sudo apt install -y chrony

Confirm the installed version — exam tasks and log messages refer to chrony 4.x on current releases:

bash
chronyd -v
output
chronyd (chrony) version 4.8 (+CMDMON +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +NTS +SECHASH +IPV6 +DEBUG)

Enable and start the daemon. Use chronyd on the RHEL family and chrony on Ubuntu and Debian:

bash
sudo systemctl enable --now chronyd
bash
systemctl is-enabled chronyd
output
enabled

Check that the unit is running before you run chronyc:

bash
systemctl status chronyd --no-pager
output
● chronyd.service - NTP client/server
     Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; preset: enabled)
     Active: active (running) since Fri 2026-08-07 21:46:28 IST; 21s ago
       Docs: man:chronyd(8)
             man:chrony.conf(5)
   Main PID: 10201 (chronyd)

If chronyc later reports 506 Cannot talk to daemon, the service is stopped — start it with sudo systemctl start chronyd (RHEL) or sudo systemctl start chrony (Ubuntu). See the systemctl command guide for restart and dependency behavior.

Turn NTP on through timedated when it was disabled:

bash
sudo timedatectl set-ntp yes

Configure Chrony as an NTP Client

Client configuration means telling chronyd which upstream servers to use, where to store drift data, and how aggressively it may step the clock at boot.

On RHEL-family systems, edit /etc/chrony.conf. A minimal client layout looks like this:

text
pool 2.rhel.pool.ntp.org iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
Directive Purpose
pool name iburst Resolve a pool hostname to several servers; iburst sends a burst of requests at startup so the first sync happens within seconds
server ip-or-name iburst Use one fixed NTP server — typical for an internal LAN server
driftfile Persist estimated clock drift between restarts
makestep 1.0 3 Step if offset exceeds one second, but only for the first three clock updates after start
rtcsync Keep the RTC aligned with the system clock

On Ubuntu and Debian, upstream pools may already exist in /etc/chrony/sources.d/ (for example ubuntu-ntp-pools.sources). You can add a .sources file there or put pool lines in /etc/chrony/chrony.conf. The drift file path is often /var/lib/chrony/chrony.drift.

To replace public pools with one internal server, swap the pool line for:

text
server 192.168.1.10 iburst

Use NTP sources your organization approves. Avoid documenting random public hostnames as if they were universal defaults — pools and regional servers change, and some networks block outbound UDP 123.

After you save the file, apply the configuration:

bash
sudo systemctl restart chronyd

On Ubuntu and Debian, restart chrony instead of chronyd. Your host needs outbound UDP port 123 to the configured servers and working DNS or routing when you use pool hostnames.


Check Synchronization Status

Verification belongs in two layers: timedatectl for a yes/no summary, then chronyc for source selection and offset detail. Red Hat recommends chronyc tracking, chronyc sources, and chronyc sourcestats to determine Chrony's synchronization state.

Re-check timedatectl after chronyd has had time to poll — with iburst, allow roughly 30–60 seconds:

bash
timedatectl show -p NTPSynchronized --value
output
no

When synchronization succeeds, this property changes to yes while NTP service stays active.

chronyc tracking shows which source is in use and whether chrony considers the clock synchronized:

bash
chronyc tracking
output
Reference ID    : 00000000 ()
Stratum         : 0
Ref time (UTC)  : Thu Jan 01 00:00:00 1970
System time     : 0.000000000 seconds fast of NTP time
Last offset     : +0.000000000 seconds
RMS offset      : 0.000000000 seconds
Frequency       : 0.000 ppm slow
Residual freq   : +0.000 ppm
Skew            : 0.000 ppm
Root delay      : 1.000000000 seconds
Root dispersion : 1.000000000 seconds
Update interval : 0.0 seconds
Leap status     : Not synchronised

When a source is selected, Leap status reads Normal, Reference ID shows the server IP or a coded name, and Stratum is a small positive number (usually 2–4 for internet pools). System time and Last offset then report sub-second skew instead of zeros.

List upstreams and read the selection markers with chronyc sources -v:

bash
chronyc sources -v

The legend at the top explains the columns. Key markers:

  • ^* — current best source (your clock follows this server)
  • ^+ — combined candidate
  • ^? — unreachable or not yet usable
  • Reach — octal register of recent poll success; 377 means the last eight polls succeeded

While upstreams are still unreachable, every row may show ^? and Reach 0:

output
MS Name/IP address         Stratum Poll Reach LastRx Last sample
===============================================================================
^? ntp2.ggsrv.de                 0   6     0     -     +0ns[   +0ns] +/-    0ns

After connectivity works, one line carries ^* and non-zero Reach, similar to:

output
^* time.cloudflare.com           3   6   377    12   -245us[ -312us] +/-   22ms
^+ 162.159.200.1                 3   6   377    10  +1200us[+1200us] +/-   45ms

Hostnames and offsets vary by site; focus on ^* and healthy Reach.

chronyc sourcestats reports per-source stability — useful when one peer looks selectable but oscillates:

bash
chronyc sourcestats
output
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
ntp2.ggsrv.de               0   0     0     +0.000   2000.000     +0ns  4000ms

When a source is in use, NP (number of samples) increases and Offset settles near zero.

Count online sources:

bash
chronyc activity
output
200 OK
8 sources online
0 sources offline

online means chronyd currently considers the source available for polling. It does not prove that valid NTP replies are arriving; use chronyc sources -v and its Reach value for that.


Force or Accelerate Clock Correction

Normal operation slews small drift. Two chronyc patterns cover the common admin cases: applying a correction chrony is already working toward, and forcing a fresh measurement when the clock is badly wrong.

Apply an in-progress slew immediately

With chronyd running, makestep with no arguments does not request a new NTP measurement. It converts any correction that chronyd is already slewing into an immediate clock step:

bash
sudo chronyc makestep
output
200 OK

200 OK means chronyd accepted the request. Use this when tracking already shows a non-zero offset being slewed and you want the jump now instead of waiting for gradual adjustment. A step can disturb time-sensitive applications — use a maintenance window on production systems.

Force a fresh measurement after large drift

After a VM resume or snapshot restore, the clock may be far off and chrony may still be slewing slowly. Chrony upstream documents combining makestep threshold limit with burst when you want a new measurement followed by a possible immediate step:

bash
sudo chronyc makestep 0.1 1
bash
sudo chronyc burst 1/2

The first command allows one of the next clock updates to step when the correction exceeds 0.1 seconds. burst 1/2 asks chronyd to poll sources quickly and obtain a fresh measurement. Wait a few seconds, then verify with chronyc tracking and chronyc sources -v.

The makestep 1.0 3 line in chrony.conf is separate: it allows automatic steps only for the first three updates after start when the offset exceeds one second. After that, chrony slews unless you use chronyc makestep as above.

One-shot sync with chronyd -q

For a one-shot sync without leaving the daemon running — common in scripts — stop the service and run chronyd -q:

bash
sudo systemctl stop chronyd
bash
sudo chronyd -q 'pool pool.ntp.org iburst maxsources 4'

When configuration directives are supplied as command-line arguments, Chrony ignores the normal configuration file and treats each argument as a configuration directive. When you pass a server or pool directive directly to chronyd, those command-line directives replace the normal configuration-file input for that run. -q sets the system clock once and exits. Settings from /etc/chrony.conf are not merged automatically for that invocation.

When a server responds, chrony prints the measured offset, steps the system clock once, and exits:

output
2026-08-07T16:15:16Z chronyd version 4.8 starting (+CMDMON +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +NTS +SECHASH +IPV6 +DEBUG)
2026-08-07T16:15:22Z System clock wrong by 0.004855 seconds (step)
2026-08-07T16:15:22Z chronyd exiting

If every upstream is unreachable, you get a failure line instead:

output
2026-08-07T16:15:16Z chronyd version 4.8 starting (+CMDMON +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +NTS +SECHASH +IPV6 +DEBUG)
2026-08-07T16:15:16Z No suitable source for synchronisation
2026-08-07T16:15:16Z chronyd exiting

Start the service again when finished:

bash
sudo systemctl start chronyd

On Ubuntu and Debian, stop and start chrony rather than chronyd.


Configure Timezone and Hardware Clock

NTP fixes clock accuracy; timezone fixes how local time is displayed. The two are related but configured separately.

Set the timezone with timedatectl (full examples in the timedatectl command cheat sheet):

bash
sudo timedatectl set-timezone Asia/Kolkata

Confirm:

bash
timedatectl show -p Timezone --value
output
Asia/Kolkata

Keep RTC in local TZ: no unless you have a specific reason to store local time in the hardware clock — UTC in the RTC avoids daylight-saving ambiguity at boot.

With rtcsync in chrony.conf, chrony copies the corrected system clock to the RTC about every eleven minutes. That helps the next boot start near correct time, especially on VMs — see Fix VM wrong time after reboot when the RTC and hypervisor fight chrony.

Avoid timedatectl set-time for routine fixes when NTP should be authoritative. Manual clock setting is for initial bootstrap or disaster recovery when no NTP source is reachable.


Diagnose Chrony Synchronization Problems

Symptom Likely cause Fix
System clock synchronized: no but NTP active Sources not yet polled or all unreachable Wait 30–60 seconds after restart; run chronyc sources -v and check Reach
Every source shows ^? or Reach 0 Firewall, routing, or blocked UDP 123 Allow outbound NTP; verify connectivity and DNS
506 Cannot talk to daemon chronyd not running sudo systemctl start chronyd (RHEL) or chrony (Ubuntu)
chronyd -q — no suitable source No server responded Check pool or server name, DNS, and UDP 123
Edited wrong file on Ubuntu Pools only in sources.d Run grep -r pool /etc/chrony/ to see active upstreams
makestep returns OK but offset stays large No ^* source or correction still slewing Run chronyc makestep 0.1 1 then chronyc burst 1/2; confirm ^* in chronyc sources -v
Large offset after VM resume Guest clock stale; chrony slewing slowly chronyc makestep 0.1 1 and chronyc burst 1/2; review VM time-sync settings
Service fails after config edit Syntax error or SELinux context on config journalctl -u chronyd -b; restore chrony.conf permissions and run restorecon on RHEL with SELinux

On RHEL with SELinux enforcing, /etc/chrony.conf must carry the correct label (etc_t). Copying a config from /tmp without restorecon can leave chronyd unable to read the file.


Configure Chrony as an NTP Server

IMPORTANT
Beyond the RHCSA client requirement. Exam tasks expect you to configure this host as an NTP client and verify synchronization. Serving time to other machines is useful in labs and air-gapped networks but is not the default RHCSA focus.

When a host already synchronizes to trusted upstreams, you can answer NTP queries for other systems on your LAN.

On the server, add allow for the client subnet in chrony.conf (RHEL) or under /etc/chrony/conf.d/ (Ubuntu):

text
allow 192.168.0.0/24

Without allow, chronyd acts as a client only and ignores inbound NTP requests.

If the server has no internet upstream but must still answer clients — only in controlled labs — some admins add local stratum 10. That serves the local unsynchronized clock and can mislead clients if used carelessly.

Restart the service and open UDP 123 on the server firewall. On RHEL-family systems with firewalld:

bash
sudo systemctl restart chronyd
bash
sudo firewall-cmd --permanent --add-service=ntp
bash
sudo firewall-cmd --reload

On Ubuntu and Debian, firewall syntax depends on which firewall you use — see open a port in Linux for your setup.

On a client VM, point chrony.conf at the server:

text
server 192.168.0.113 iburst
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync

After restart on the client, chronyc sources -v should show ^* beside the server IP and chronyc tracking should list that address as Reference ID.

On the server, confirm the allow ACL is serving clients after a client has contacted it:

bash
sudo chronyc clients

The output lists client addresses that have recently used this host as an NTP server.


Chrony Quick Reference

Task Command
Show time, timezone, NTP summary timedatectl status — see timedatectl command
Enable NTP through systemd sudo timedatectl set-ntp yes
Client config (RHEL family) /etc/chrony.conf
Client config (Ubuntu/Debian) /etc/chrony/chrony.conf and /etc/chrony/sources.d/
Service (RHEL family) sudo systemctl enable --now chronyd
Service (Ubuntu/Debian) sudo systemctl enable --now chrony
Tracking summary chronyc tracking
Sources and selection markers chronyc sources -v
Per-source statistics chronyc sourcestats
Step in-progress slew now sudo chronyc makestep
Fresh measurement + permitted step sudo chronyc makestep 0.1 1 then sudo chronyc burst 1/2
One-shot sync sudo chronyd -q 'server ADDR iburst' (daemon stopped; CLI replaces config file)
LAN server ACL allow SUBNET in chrony.conf
List NTP clients on server sudo chronyc clients

Common server / pool options: iburst (fast initial sync), minpoll / maxpoll (poll interval as (2^N) seconds; defaults are often 6 and 10), makestep (boot-time step policy), rtcsync (RTC update), allow (serve clients).


References


Summary

You configure Chrony on Linux by installing the chrony package, enabling chronyd (or chrony on Debian-family systems), and pointing /etc/chrony.conf at trusted pool or server lines with iburst, driftfile, makestep, and rtcsync. timedatectl shows whether a network time service is active and whether the system considers the clock synchronized; chronyc tracking, chronyc sources -v, and chronyc sourcestats show Chrony's actual reference source, stratum, and reachability.

The common exam pitfall is treating NTP service: active as proof of sync — always confirm System clock synchronized: yes and a ^* marker in chronyc sources -v. chronyc makestep with no arguments steps a correction chrony is already slewing; after large VM drift, chronyc makestep 0.1 1 followed by chronyc burst 1/2 obtains a fresh measurement and permits an immediate step. chronyd -q performs a one-shot sync for scripts, using only the directives you pass on the command line. Timezone and RTC settings stay separate from NTP — use timedatectl set-timezone and keep rtcsync so reboots start from a sane hardware clock.

Serving time to other hosts requires allow on the server, UDP 123 through the firewall (firewall-cmd --add-service=ntp on RHEL with firewalld), and verification with chronyc clients — optional beyond RHCSA client work. For VM clocks that jump after every reboot, trace RTC and hypervisor interaction in the dedicated VM time guide linked above.


Frequently Asked Questions

1. How do I configure Chrony as an NTP client on RHEL?

Install chrony, set pool or server lines in /etc/chrony.conf, enable and start chronyd, then confirm with timedatectl and chronyc sources -v. On Ubuntu and Debian the main file is /etc/chrony/chrony.conf and the systemd unit is usually named chrony.

2. How do I check if Chrony is synchronized?

Run timedatectl and look for System clock synchronized: yes with NTP service: active. Then run chronyc tracking for Leap status: Normal and chronyc sources -v to see which upstream is selected with ^*.

3. How do I force Chrony to sync time immediately?

chronyc makestep immediately applies a correction that chronyd is already slewing. To obtain a fresh measurement and permit an immediate step, use chronyc makestep 0.1 1 followed by chronyc burst 1/2. For a one-shot sync without the daemon, stop chronyd and run sudo chronyd -q with your pool or server line. The makestep 1 3 line in chrony.conf allows an initial step on the first few updates after boot.

4. Where is the Chrony configuration file on RHEL vs Ubuntu?

On RHEL, Rocky Linux, AlmaLinux, and CentOS Stream, edit /etc/chrony.conf and manage chronyd. On Ubuntu and Debian, the main file is /etc/chrony/chrony.conf and upstream pools often live under /etc/chrony/sources.d/.

5. Can I use Chrony as an NTP server for other hosts?

Yes. Add allow with your client subnet in chrony.conf on the server, open UDP port 123, restart chronyd or chrony, and point clients at server YOUR_SERVER_IP iburst. Use local stratum 10 only when the server has no external sources and you accept serving time from an unsynchronised local clock.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.

  • Go (programming language)
  • Python (programming language)
  • DevOps
  • Computer Security
  • Cloud Computing
  • Kubernetes
  • Linux
  • Ansible (software)