How to Troubleshoot systemd Timers: 7 Practical Checks

Linux systemd timers troubleshooting: a penguin administrator examining a failed scheduled task on a monitoring dashboard. Linux & Administration
Troubleshoot systemd timers on Linux with 7 practical checks. Learn why scheduled tasks fail, how to inspect services and logs, and safely diagnose missed runs.
🐧 Linux & Administration 🎓 Mini-course · Lesson 03/03 🔍 Troubleshooting

Your systemd Timer Is Active. Why Didn’t the Job Run?

An active timer does not mean the script completed. Follow the evidence from the next scheduled trigger to the service exit status and journal. These seven checks help you troubleshoot systemd timers without randomly restarting production jobs.

✍️ Servers Academy Editorial Team ⏱️ Beginner → intermediate 🔎 Mostly read-only commands
Linux penguin detective troubleshooting systemd timers by investigating service errors and journal logs in a cozy study
A little detective follows the evidence. On a Linux server, the clues live in the timer, its service, and the journal. Illustration, not a screenshot of actual output.
🧭 Seven checks Follow the trigger → service → result
📋 Real commands Inspect with systemctl and journalctl
🛡️ Safe approach Observe first; rerun only when appropriate
🎓 Mini-course: Linux systemd Timers Browse mini-courses ↗
01 Foundations OnCalendar, OnBootSec and Persistent
02 Practice Create and verify a timer
03 Troubleshooting · You are here Trace failures, missed runs and logs

First, find out which part failed

A systemd timer tells Linux when to start work. A service unit tells systemd what to run. The program then succeeds, fails, or produces an unexpected result. Troubleshooting systemd timers as separate stages saves time.

Quick answer: If a systemd timer is not running a task, first inspect the .timer with systemctl status and systemctl list-timers --all. Then inspect the matching .service and its journalctl entries. Check the calendar expression, unit names, exit status and execution environment before making changes.

The commands below use sa-timer-demo.timer and sa-timer-demo.service from the preceding practice lesson. They are example names, not systemd built-ins. Replace them with the exact units on your machine. The initial checks are read-only; a later manual start is clearly marked as an action.

🕰️ The schedule The timer never started or has no expected next occurrence.
⚙️ The workload The service was triggered but failed before completing.
📂 The output Execution succeeded, but its result is missing or in the wrong place.
01

Check whether the timer is actually active

Start with the scheduler, not with a restart. A timer may be installed but disabled, enabled for future boots but inactive now, or not loaded at all. These states are different, and they are the first clues when systemd timers stop triggering work.

Terminal · read-only timer checks
systemctl status sa-timer-demo.timer --no-pager -l
systemctl is-enabled sa-timer-demo.timer
systemctl is-active sa-timer-demo.timer

Look for the Loaded and Active lines. enabled describes whether the timer is configured to start automatically; active describes its state now. Neither proves that the service ran successfully.

02

Compare the expected and actual next trigger

A healthy timer can still run later than you expect. First inspect the next and last trigger timestamps, then compare the schedule in the actual unit file with the system clock.

Terminal · inspect schedule and clock
systemctl list-timers --all sa-timer-demo.timer
systemctl cat sa-timer-demo.timer
timedatectl status
systemd-analyze calendar --iterations=3 '*-*-* *:00/5:00'

The final command parses the five-minute example from Lesson 02; it does not read your live timer automatically. For another schedule, copy its actual OnCalendar= value into the calendar command. A calendar expression describes wall-clock times; the machine’s timezone and clock matter when diagnosing systemd timers.

03

Verify which service the timer activates

By default, example.timer activates example.service. But a timer can override that relationship with Unit=. If you inspect the wrong service, you may conclude nothing ran even when systemd timers activated a different target.

Terminal · inspect the real unit definitions
systemctl cat sa-timer-demo.timer
systemctl cat sa-timer-demo.service
systemctl list-timers --all sa-timer-demo.timer

Read the ACTIVATES column when it is available, and compare it with the timer’s Unit= setting. Check that the service exists and points to the intended executable.

Important: if the target service is already active when the timer elapses, systemd does not start a second instance of that same unit. This protects against a common kind of overlap, but it also means one long-running service can make later timer events appear to do nothing.

04

Read the service exit result—not just “inactive”

Now inspect the workload itself. For a typical Type=oneshot job, inactive (dead) after completion can be completely normal. You need the last result, exit information and matching journal messages.

Terminal · see what the service reported
systemctl status sa-timer-demo.service --no-pager -l
systemctl show sa-timer-demo.service -p ActiveState -p Result -p ExecMainStatus

A nonzero exit status or a failed unit is a reason to investigate. Result=success describes the service manager’s recorded result—not proof that a backup file is valid or that a notification reached its destination. Check the real output separately; systemd timers cannot verify application-level results for you.

Message or state Likely meaning What to check next
inactive (dead) after oneshot Often a normal completed run Recent journal entry and workload output.
status=203/EXEC systemd could not execute the program ExecStart= path, execute permission and script interpreter.
status=217/USER Failure while preparing user credentials The configured User= and account availability.
Result=exit-code A command returned a failure status Service journal and the program’s own error output.

The numeric exit statuses are systemd execution status names, not universal application exit codes. See systemd.exec(5) for the complete list.

05

Use journalctl to build a timeline

Instead of reading unrelated system messages, narrow the journal to this service and the time window when the problem occurred. Look for the first useful error before the final failed status.

Terminal · logs for this boot
sudo journalctl -u sa-timer-demo.service -b --since "-2 hours" --no-pager -o short-iso
sudo journalctl -u sa-timer-demo.timer -b -n 30 --no-pager

The first command shows service entries from the current boot within the last two hours. The second examines timer-unit messages, if any were recorded. A quiet timer journal does not, by itself, prove that no trigger occurred. If the service prints useful information to stdout or stderr and journal capture is configured, its journal is usually the stronger clue when systemd timers seem silent.

For investigation across restarts, repeat the service query without -b and choose a wider date range. Older entries may not be present when the journal is volatile, rotated or otherwise unavailable. If you need a detailed guide to filters, see journalctl Explained .

06

Validate configuration; rerun only a harmless job

If the timer definition and service logs still do not settle the question, verify the unit files. This check does not start the service or modify the schedule.

Terminal · validate without running the workload
sudo systemd-analyze verify /etc/systemd/system/sa-timer-demo.timer /etc/systemd/system/sa-timer-demo.service
ls -l /usr/local/bin/sa-timer-demo.sh
systemctl cat sa-timer-demo.service

For the read-only demonstration script from Lesson 02, you may then start the service manually to separate a script failure from a scheduling failure. Do not do this with backups, migrations, payments or destructive maintenance scripts until you know the consequences of a second run.

Action · only for the disposable Lesson 02 demo
sudo systemctl start sa-timer-demo.service
sudo journalctl -u sa-timer-demo.service -n 20 --no-pager

In the demo, look for the line beginning with sa-timer-demo: executed at. If the manual start works but the scheduled event does not happen, return to the timer state and next-trigger checks. If the manual start fails, examine the service configuration, script permissions, paths and runtime environment first.

07

Explain missed runs, reboots and overlaps

A timer can be correctly configured yet not run while the machine is shut down. The important question is what you expect from systemd timers when the machine comes back online.

Setting or situation What it means Decision
OnCalendar= Uses calendar time. Inspect timezone, schedule and any catch-up requirement.
Persistent=true For calendar timers, can trigger a catch-up activation when the timer starts after one or more occurrences were missed. Use when one catch-up run is useful; it is not a queue of every missed interval.
OnBootSec= Elapsed-time trigger measured from boot. Useful for tasks tied to boot, not a fixed wall-clock time.
Target service already active The timer does not spawn a second instance of the same active unit. Inspect runtime and decide whether the next run needs different timing.

A machine turned off for three scheduled daily occurrences does not automatically replay three separate runs on startup just because Persistent=true is set. The stored trigger state may cause an activation after the timer comes online; the service still needs to finish successfully.

This topic is introduced in Lesson 01 and specified in the systemd.timer(5) manual . If the schedule is too frequent for the workload duration, revisit the task design instead of assuming every interval must produce another concurrent process.

Choose the next check from the symptom

Use this as a practical decision table when someone says “the systemd timer is not working.” When troubleshooting systemd timers, start with evidence; change configuration only after identifying a specific problem.

Observed symptom First check Likely next action
The timer is inactive. systemctl status NAME.timer Confirm desired enablement/start state before starting it.
The timer has no expected NEXT time. systemctl list-timers --all Check the actual OnCalendar= expression, clock and timer options.
Timer active; script output missing. journalctl -u NAME.service Identify whether the service ran and what it reported.
Service failed to execute. systemctl status NAME.service Check the exact failure status and executable path.
Oneshot service shows inactive (dead). Recent journal plus output artifact Do not restart solely to make the service show active.
Nothing ran after power-off. Calendar timer and Persistent= Decide whether one catch-up run is required.

A short hypothetical investigation

Illustrative scenario · not a reported production incident or tested server

Situation: A student sets up the disposable five-minute sa-timer-demo from Lesson 02. At the end of the lab, the timer says active (waiting), but the student cannot find a fresh output line in the journal.

Check 1: systemctl list-timers --all sa-timer-demo.timer shows a future NEXT time. That is evidence the timer is waiting—not that its service has already finished.

Check 2: systemctl cat sa-timer-demo.timer shows the target sa-timer-demo.service. The student verifies the service independently using the safe manual test.

Check 3: if the service prints the expected sa-timer-demo: executed at... line when started manually, the script itself is probably not the immediate issue. They wait for the next scheduled window, allow for AccuracySec, then inspect recent service entries. If the manual test instead returns a failure, they investigate that error before changing the timer.

Takeaway: one status screen cannot answer every question. For systemd timers, timer state establishes scheduling; service status and journal messages establish execution. The missing line might be a timing misunderstanding, a service failure, or a logging query that was too narrow.

Check your understanding

1. The timer is active. Can you conclude the task succeeded?

No. Timer activity concerns scheduling. Read the service result and verify the actual output or artifact.

2. Why might a successful oneshot service say “inactive (dead)”?

The finite task ran and exited. Unless configured to remain active, a successful oneshot service can return to the inactive state normally.

3. What is the safest first response to a missing scheduled run?

Inspect the timer’s active state and next trigger, then check its target service and available journal entries. Do not blindly rerun a production task.

4. Does Persistent=true replay every missed daily run?

No. For an OnCalendar timer, it can cause a catch-up activation when a scheduled occurrence was missed while the timer was inactive. It is not a replay queue for each missed occurrence.

5. What should you suspect if a script works in an interactive shell but fails as a service?

Check the service’s user, executable paths, working directory, environment, permissions and sandboxing restrictions.

Official documentation and related lessons

Systemd features vary across versions. Use systemctl --version on your server and prefer the manuals installed with your distribution when settings differ.

Responsible editorial team: Servers Academy Editorial Team. The case study is explicitly hypothetical; no production run, recovery test or benchmark is claimed.
Rate article
Servers Academy
Add a comment