“Could not step system clock”是chronyd因缺少CAP_SYS_TIME能力而无法直接跳变系统时间导致的启动失败错误;根本原因是非特权用户进程被内核禁止调用clock_settime(),需通过setcap添加能力并配置systemd service的CapabilityBoundingSet和AmbientCapabilities来修复。

chronyd 启动时提示 “Could not step system clock” 是什么问题
这是 chronyd 在初始化阶段尝试用 clock_settime() 直接跳变系统时间(即“step”)失败导致的,不是警告,是硬性错误,会导致服务退出。根本原因通常是内核禁止非特权进程修改系统时钟,而 chronyd 默认以普通用户(如 _chrony)运行,没有 CAP_SYS_TIME 能力。
为什么 adjtime(2) 成功但 clock_settime(2) 失败
adjtime() 是渐进式调速(slew),仅调整时钟频率,不改变当前时间戳,普通用户可调;clock_settime(CLOCK_REALTIME, ...) 是直接写入新时间,属于高危操作,受 Linux capability 限制。chronyd 启动时若检测到系统时间偏差过大(默认 > 0.128 秒),会优先尝试 step(更快收敛),失败后才 fallback 到 slew —— 但若 step 失败且未配置允许降级,就直接报错退出。
-
chronyd -d -x可强制只用 slew 模式(绕过 step),适合调试 - 实际生产中不建议长期用
-x,它无法修正大偏差,可能让 NTP 同步失效 - 检查偏差大小:
chronyc tracking中的System time offset
修复 “Could not step system clock” 的三种可行方式
核心是让 chronyd 进程获得 CAP_SYS_TIME,而非改用 root 运行(不安全):
- 给 chronyd 二进制文件添加 capability:
sudo setcap cap_sys_time+ep /usr/bin/chronyd - 确认生效:
getcap /usr/bin/chronyd应输出/usr/bin/chronyd = cap_sys_time+ep - 若使用 systemd,需在 service 文件中显式声明能力(否则 setcap 可能被忽略):
CapabilityBoundingSet=CAP_SYS_TIME和AmbientCapabilities=CAP_SYS_TIME - 重启服务:
sudo systemctl restart chronyd,再查journalctl -u chronyd -n 20
/etc/chrony.conf 中的 makestep 配置影响 step 行为
makestep 指令控制 chronyd 是否以及何时执行 step,它不解决权限问题,但决定是否触发该错误:
-
makestep 1.0 -1:偏差 ≥1 秒时无条件 step(最可能触发错误) -
makestep 0.128 3:仅在启动后前 3 秒内、偏差 ≥128ms 时 step(更保守) -
makestep 0 0:完全禁用 step(等同于-x,不推荐) - 注意:即使配置了
makestep,若 capability 缺失,仍会报错退出,不会静默 fallback
setcap 在某些发行版(如 RHEL 8+/CentOS Stream)的 systemd 环境下并不生效,必须补全 CapabilityBoundingSet 和 AmbientCapabilities 才能落地。










