Your systemd service is reporting active (exited) because the service’s main process successfully started, did its job, and then terminated cleanly. systemd interprets a clean exit as the service completing its intended work and then exiting, rather than running indefinitely like a daemon.

Common Causes and Fixes for active (exited) State:

  1. One-Shot Service Configuration:

    • Diagnosis: The service is intended to run once and exit. This is a valid systemd service type. Check the Type= directive in your service’s .service file. If it’s set to oneshot, this is expected behavior.
    • Fix: No fix is needed if this is the intended behavior. If it’s not intended, change Type=oneshot to Type=simple (or forking if appropriate) in the .service file and reload systemd:
      sudo systemctl daemon-reload
      sudo systemctl restart your_service_name.service
      
    • Why it works: Type=simple tells systemd that the main process is the service itself and it should be considered running as long as that process is alive. Type=forking indicates the parent process will exit after forking a child daemon process.
  2. Service Script Exits Immediately:

    • Diagnosis: The script executed by ExecStart= in the .service file is running, but it’s exiting very quickly, perhaps due to an immediate error or a condition that causes it to finish. Check the service’s logs for any output from the script.
      sudo journalctl -u your_service_name.service -f
      
    • Fix: Debug the script itself. Add set -x at the beginning of your shell script to trace execution. Identify the line causing the premature exit. For example, a missing configuration file or an incorrect command argument might cause this.
      # Example fix: Ensure a required file exists before proceeding
      if [ ! -f /etc/your_app/config.yaml ]; then
          echo "Error: Configuration file missing." >&2
          exit 1
      fi
      
    • Why it works: By identifying and correcting the condition that causes the script to exit early, you allow the script to continue running or perform its intended long-running task.
  3. Incorrect Type= Setting for a Daemon:

    • Diagnosis: You’ve configured a service that should be a long-running daemon (like a web server or database) but have Type=oneshot or Type=simple where the process forks and the parent exits. The systemd logs will show the ExecStart process exiting.
      sudo journalctl -u your_service_name.service
      
    • Fix: If your application forks a child process and the parent exits, change Type= to forking. You may also need to specify PIDFile= in the .service unit so systemd can track the daemon’s main process.
      [Service]
      Type=forking
      PIDFile=/run/your_app.pid
      ExecStart=/usr/bin/your_daemon_start_command
      
      Then reload and restart:
      sudo systemctl daemon-reload
      sudo systemctl restart your_service_name.service
      
    • Why it works: Type=forking tells systemd to expect the ExecStart process to fork and the parent to exit. systemd then monitors the child process using the PIDFile to determine the service’s status.
  4. RemainAfterExit=yes Not Set for One-Shot Success:

    • Diagnosis: You have a Type=oneshot service that successfully completes its task, but you want systemd to consider it "active" even after it exits, perhaps because it sets up some system state. The service runs and exits as expected, but systemd doesn’t keep track of it as "active."
    • Fix: Add RemainAfterExit=yes to the [Service] section of your .service file.
      [Service]
      Type=oneshot
      ExecStart=/usr/bin/your_setup_script.sh
      RemainAfterExit=yes
      
      Reload systemd and restart the service.
      sudo systemctl daemon-reload
      sudo systemctl restart your_service_name.service
      
    • Why it works: RemainAfterExit=yes instructs systemd to consider the service active as long as any of its instantiated units are active, even if the main ExecStart process has exited. This is useful for services that perform a setup action and then are expected to remain "enabled" without a running process.
  5. Incorrect ExecStop= or ExecStopPost= Logic:

    • Diagnosis: If your service is supposed to be a long-running daemon, but it’s exiting unexpectedly, it might be that systemd is trying to stop it, and the ExecStop= command is causing it to exit prematurely or incorrectly. Check the logs for stop-related messages.
      sudo journalctl -u your_service_name.service -b
      
    • Fix: Review the ExecStop= command in your .service file. Ensure it correctly signals the daemon to stop and exits cleanly itself. If the daemon doesn’t have a specific stop command, you might not need ExecStop=, as systemd will send SIGTERM by default. If it’s a forking type, ensure ExecStop= correctly terminates the daemon and exits.
      [Service]
      Type=forking
      ExecStart=/usr/sbin/your_daemon -d
      ExecStop=/usr/bin/kill -s TERM $MAINPID
      
    • Why it works: A correctly defined ExecStop= ensures that systemd can gracefully shut down the daemon process when requested, preventing it from exiting in a way that systemd interprets as an error.
  6. Dependencies Causing Premature Exit:

    • Diagnosis: The service might be exiting because a dependency it relies on (e.g., a network mount, another service) is not available or fails during the service’s execution. Check Requires= and Wants= directives in the .service file and their status.
      systemctl list-dependencies your_service_name.service
      sudo journalctl -u your_service_name.service -f
      
    • Fix: Ensure all dependencies are correctly configured and running. If a Requires= dependency fails, systemd will often stop the dependent service. For example, if your service needs a network connection, ensure After=network-online.target and Wants=network-online.target are present.
      [Unit]
      Description=My Service
      After=network-online.target
      Wants=network-online.target
      
      Reload and restart.
      sudo systemctl daemon-reload
      sudo systemctl restart your_service_name.service
      
    • Why it works: systemd manages service startup order and dependencies. By correctly declaring dependencies, you ensure that required resources are available before your service starts, preventing it from failing due to missing prerequisites.

After resolving these, the next error you might encounter is a failed state if the service now crashes instead of exiting cleanly, or a timeout if it takes too long to start.

Want structured learning?

Take the full Systemd course →