Linux DEPCYCLCritical

Resolving systemd circular dependency: causes and solutions

This article explains what a cyclic dependency in systemd is, why it occurs, and how to fix it. You will learn how to analyze unit dependencies and make changes to restore system functionality.

Updated at February 16, 2026
15-30 min
Medium
FixPedia Team
Применимо к:systemd v239+Ubuntu 18.04+Debian 10+Fedora 30+

What a systemd cyclic dependency error means

During boot, systemd builds a dependency graph between units (services, targets, sockets, etc.). A cyclic dependency occurs when two or more units reference each other as required (via Requires, Wants, PartOf, or After combined with other directives), forming a closed loop. systemd cannot determine the startup order for such units and aborts the process, displaying an error.

Typical symptoms:

  • Messages appear in logs (journalctl -xe or systemctl status <unit>): Dependency cycle detected: foo.service → bar.service → foo.service.
  • Services involved in the cycle transition to failed or dead state.
  • The system may hang during the boot phase (e.g., at Starting...).
  • The systemctl list-dependencies command for the problematic unit fails or shows a recurring chain.

This error is critical: it prevents at least one service from starting, and in the worst case, halts the entire system boot.

Common causes

  1. Misconfigured dependency directives in unit files. For example, serviceA.service has Requires=serviceB.service, while serviceB.service has Requires=serviceA.service.
  2. Dependency chains through target units. For instance, multi-user.target depends on network.target, which depends on a service that requires multi-user.target.
  3. Conflicting directives. Combining Requires/Wants with Conflicts or Before/After can create an implicit cycle.
  4. Package errors. When installing third-party software, its unit files may contain cycles, especially if the package incorrectly declares dependencies.
  5. Manual editing without verification. An administrator might have added a dependency without accounting for existing connections.

Resolution methods

Method 1: Manual analysis and editing of unit files

This method is suitable when you know the approximate names of the problematic units.

  1. Identify the units involved in the cycle. Use:
    systemd-analyze critical-chain
    

    This command shows the boot chain and indicates where a delay or cycle occurs. Look for repeating unit names.
    Or for a specific unit:
    systemctl list-dependencies <unit_name> --all
    

    If a cycle exists, the output will be interrupted or show the same units multiple times.
  2. Visualize the dependency graph (optional but helpful). Install graphviz:
    sudo apt install graphviz   # Debian/Ubuntu
    sudo yum install graphviz   # CentOS/RHEL
    

    Then generate an SVG file:
    systemd-analyze plot > dependencies.svg
    

    Open dependencies.svg in a browser and look for a cycle (a closed loop of arrows).
  3. Locate the unit files. For each unit in the cycle, determine its source:
    systemctl status <unit_name> | grep Loaded
    

    The output shows the path: /etc/systemd/system/ (user overrides) or /lib/systemd/system/ (from a package).
  4. Edit the unit files. Open each file in an editor (e.g., sudo nano /path/to/unit.service). Find directives like Requires=, Wants=, After=, Before=. Remove or modify the reference that closes the cycle. For example, if serviceA requires serviceB and serviceB requires serviceA, remove one dependency (often you can keep Wants= instead of Requires= or remove After=).
  5. Reload the systemd configuration:
    sudo systemctl daemon-reload
    
  6. Verify the result:
    systemctl status <unit_name>
    systemd-analyze critical-chain
    

    The error should disappear.

Method 2: Using systemd-analyze verify for automatic checking

systemd-analyze verify checks the syntax and logic of unit files, including cycles.

  1. Run verification for all units:
    sudo systemd-analyze verify --fail --no-pager
    

    The --fail flag makes the command exit with a non-zero code on errors, and --no-pager disables paged output. The output will list files and lines with issues, including cyclic dependencies.
  2. If the output is too long, check individual units:
    sudo systemd-analyze verify /etc/systemd/system/foo.service
    
  3. Fix the indicated files as in Method 1.
  4. Reload the daemon and verify.

Method 3: Temporarily disabling problematic units (mask)

If the cycle prevents system boot (e.g., you cannot access a shell), boot into recovery mode or use a live-USB.

  1. Identify the cycle via systemd-analyze from recovery mode, or if the system partially boots, check journalctl -b -1 (logs from the previous boot).
  2. Temporarily mask one unit in the cycle:
    sudo systemctl mask <unit_name>
    

    This creates a symlink to /dev/null, preventing the unit from starting.
  3. Reboot the system. It should boot without the error (though functionality related to the masked unit will be unavailable).
  4. After booting, fix the unit files (Method 1), then unmask:
    sudo systemctl unmask <unit_name>
    sudo systemctl daemon-reload
    sudo systemctl restart <unit_name>
    

Method 4: Updating or reinstalling the package

If the cycle is caused by a package from a repository (e.g., after an update):

  1. Find the package owning the unit:
    dpkg -S /lib/systemd/system/foo.service   # Debian/Ubuntu
    rpm -qf /usr/lib/systemd/system/foo.service   # CentOS/RHEL
    
  2. Update the package to the latest version—the issue may have been fixed in a newer release:
    sudo apt update && sudo apt upgrade <package_name>   # Debian/Ubuntu
    sudo yum update <package_name>   # CentOS/RHEL
    
  3. If updating doesn't help, reinstall the package:
    sudo apt install --reinstall <package_name>   # Debian/Ubuntu
    sudo yum reinstall <package_name>   # CentOS/RHEL
    

    Reinstalling replaces unit files with defaults, potentially removing the cycle.
  4. Reload systemd and verify.

Method 5: Using systemd-analyze dump for deep analysis

If previous methods fail, obtain a full dump of systemd's state:

  1. Create a dump:
    sudo systemd-analyze dump > systemd-dump.txt
    
  2. Manually search for cycles. Open the file and find all occurrences of Requires=, Wants=, After= for suspect units. Map the chain on paper or in a graphics editor.
  3. Pay special attention to "want" and "require" chains. Cycles often form via WantedBy= in [Install] sections. For example, serviceA has WantedBy=multi-user.target, and serviceB (which depends on serviceA) also has WantedBy=multi-user.target and Requires=serviceA. This isn't always a cycle, but if serviceA also requires serviceB, a cycle will occur.
  4. Fix the files and reload the daemon.

Prevention

  • Test unit files before installation. Use systemd-analyze verify <file>.
  • Avoid mutual Requires=. If service A needs service B, Requires=B in A is sufficient. Do not add a reverse dependency in B unless absolutely necessary.
  • Use Wants= instead of Requires= if the dependency is not critical. This reduces cycle risk.
  • Group services via targets. Create a target unit (e.g., myapp.target) and add services to it via WantedBy=. Then enable only the target.
  • Regularly check dependencies after changes: systemctl list-dependencies <key_unit>.
  • When updating packages, review changelogs for dependency changes.
  • Keep systemd updated. Newer versions have improved dependency handling and warnings.

This article should help you quickly diagnose and resolve cyclic dependencies in systemd, restoring service and system operation.

F.A.Q.

What is a cyclic dependency in systemd?
How to detect a cyclic dependency?
Can a cyclic dependency be fixed automatically?
How to prevent cyclic dependencies when creating unit files?

Hints

Analyzing dependencies
Graph visualization
Finding problematic unit files
Editing unit files
Reloading systemd daemon
Verification and startup
FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community