--- title: systemd user service not started at boot: "Found ordering cycle ... Job deleted to break ordering cycle" date: 2026-04-24 summary: A systemd user service was inactive after every boot. The journal showed default.target "Found ordering cycle" and deleted its start job. A dependency was WantedBy=default.target and also After=default.target; removing the After= line fixed it. tags: systemd, linux, systemd-user environment: Arch Linux; systemd user manager (systemctl --user); systemd version not recorded author: shaun, written up with Claude status: published --- ## Symptoms A web front end, run as a systemd **user** service, was down after a reboot. The reverse proxy in front of it returned 502 and logged `connection refused` to the local port. The unit was `inactive (dead)` since boot, and nothing had tried to start it. The user journal from boot had this (unit names made generic): ```text default.target: Found ordering cycle: myapp-web.service/start after myappd.service/start after default.target/start - after myapp-web.service default.target: Job myapp-web.service/start deleted to break ordering cycle ``` ## Root cause Two user units: - `myappd.service`: the daemon. `WantedBy=default.target`, **and `After=default.target`**. - `myapp-web.service`: the web front end. `WantedBy=default.target`, `Requires=` and `After=myappd.service`. `WantedBy=default.target` makes the target *want* the unit. A target unit also automatically adds `After=` for everything it `Wants=` or `Requires=` (`systemd.target(5)`), so `default.target` is ordered after `myapp-web.service`. With the explicit lines that gives: ```text default.target after myapp-web.service after myappd.service after default.target ``` That is a loop. systemd breaks ordering cycles at boot by deleting one of the jobs in it, here the start job for `myapp-web.service`, so the web front end never started. A unit that is `WantedBy=` a target must not also be `After=` that same target: the target only counts as reached once the units it wants are up. ## Fix Remove `After=default.target` from the daemon's unit (`~/.config/systemd/user/myappd.service`): ```ini [Unit] Description=myapp daemon [Service] Type=simple ExecStart=/path/to/myappd Restart=on-failure RestartSec=5 [Install] WantedBy=default.target ``` Then: ```bash systemctl --user daemon-reload systemctl --user start myapp-web.service # pulls in myappd via Requires= ``` Both units came up, the local port answered, and the proxy stopped returning 502. If a user service really needs ordering, order it after a more specific unit, not after the target that wants it. Note that services with default dependencies are already ordered `After=basic.target` (`systemd.service(5)`), so you do not need to add that yourself. ## How it was found The proxy logged `connection refused` to the local port, so the back end was down rather than slow. `systemctl --user status myapp-web.service` showed `inactive (dead)` since boot, and the user journal for that boot showed the ordering-cycle message above. ## References - `systemd.target(5)`: automatic `After=` dependencies for units a target wants. - `systemd.service(5)`: implicit dependencies of service units.