Home / Alt manpages / systemd-xdg-autostart-generator(8)

  • systemd-xdg-autostart-generator(8)
  • Admin command
  • linux

Debug Autostart Apps with systemd-xdg-autostart-generator

systemd-xdg-autostart-generator turns each .desktop autostart entry into a transient systemd user service you can actually inspect and stop. This guide traces one entry all the way from its source file to the generated unit, then shows a safe way to run the generator by hand in a scratch directory. Allow about fifteen minutes. You need a systemd user session and a shell; root is not required for the inspection or the temporary test.

This guide describes systemd 255, installed here as package version 255.4-1ubuntu8.17. Generator details can vary between systemd releases, so treat the output on your own machine as authoritative.

1. Check what is installed

The generator is a user unit generator, not a command with a useful interactive interface of its own. Confirm the package and executable first:

$ systemd --version
systemd 255 (255.4-1ubuntu8.17)
$ dpkg-query -W -f='${Package} ${Version}\n' systemd
systemd 255.4-1ubuntu8.17
$ ls -l /usr/lib/systemd/user-generators/systemd-xdg-autostart-generator
-rwxr-xr-x ... /usr/lib/systemd/user-generators/systemd-xdg-autostart-generator

The exact permission line and package suffix will differ on your machine. Do not run the generator with --help: it expects output-directory arguments, so that invocation treats the word as a path and produces misleading file errors.

2. Find the source desktop entry

XDG autostart runs on .desktop files. A per-user entry normally lives under ~/.config/autostart/; system-wide entries normally live under /etc/xdg/autostart/. The XDG specification gives the user directory precedence when the same filename exists in both places.

Search without changing anything:

$ find "$HOME/.config/autostart" /etc/xdg/autostart \
    -maxdepth 1 -type f -name '*.desktop' -print 2>/dev/null
/home/USER/.config/autostart/example.desktop
/etc/xdg/autostart/example.desktop

Replace USER only in the example output, not in a command you actually paste. If one filename turns up in both directories, inspect the user copy first: a user-level Hidden=true entry can disable a system-wide entry with the same name.

Checkpoint

Inspect the relevant keys before blaming systemd.

$ sed -n '1,120p' "$HOME/.config/autostart/example.desktop"
[Desktop Entry]
Type=Application
Name=Example notifier
Exec=/usr/bin/example-notifier
OnlyShowIn=GNOME;

Pay particular attention to Hidden, X-systemd-skip, TryExec, OnlyShowIn, NotShowIn and desktop-environment-specific condition keys. Some of these stop a unit being generated at all; others become an ExecCondition that stops the service starting.

3. Reload the user manager

Generators run automatically when systemd loads or reloads its configuration. After changing a user autostart file, reload the user manager as the ordinary account:

$ systemctl --user daemon-reload

This clears old generated output, runs the user generators again and reloads the unit tree. It does not need sudo. If the command complains there is no user bus, run the check from inside the logged-in graphical session that owns the autostart entry.

Do not edit files under $XDG_RUNTIME_DIR/systemd/generator*. They are generated state and get replaced on the next reload. Edit the source .desktop file instead.

4. Inspect the generated service

The generator names each entry from its desktop filename. For example.desktop, ask the user manager for the generated unit:

$ systemctl --user cat [email protected]
# /run/user/1000/systemd/generator.late/[email protected]
# Automatically generated by systemd-xdg-autostart-generator

[Unit]
Documentation=man:systemd-xdg-autostart-generator(8)
SourcePath=/home/USER/.config/autostart/example.desktop
PartOf=graphical-session.target

[Service]
Type=exec
ExecStart=:/usr/bin/example-notifier
Restart=no
Slice=app.slice

The numeric user ID, source path, description and service details all depend on the entry. The generated unit is normally attached to graphical-session.target, and the desktop environment can start it through xdg-desktop-autostart.target. A unit may also carry an ExecCondition for desktop visibility or a vendor-specific condition.

If systemctl --user cat says the unit does not exist, check the filename-derived unit name, reload again, then inspect the source keys. Hidden=true, X-systemd-skip=true, an unusable TryExec, and an ignored desktop phase are the usual reasons nothing was generated.

5. Test the generator without touching your session

For a reproducible diagnosis, run the generator by hand with three temporary output directories. The service manager normally supplies these arguments itself; they are not options you set in the desktop file. This test uses a harmless command and a temporary XDG configuration directory:

$ testdir=$(mktemp -d /tmp/xdg-autostart-test.XXXXXX)
$ mkdir -p "$testdir/config/autostart" "$testdir/normal" \
    "$testdir/early" "$testdir/late"
$ cp "$HOME/.config/autostart/example.desktop" \
    "$testdir/config/autostart/example.desktop"
$ XDG_CONFIG_HOME="$testdir/config" XDG_CONFIG_DIRS=/nonexistent \
    /usr/lib/systemd/user-generators/systemd-xdg-autostart-generator \
    "$testdir/normal" "$testdir/early" "$testdir/late"
$ find "$testdir" -path '*.service' -type f -print
/tmp/xdg-autostart-test.ABC123/late/[email protected]

Open the resulting service to see exactly what systemd would load:

$ sed -n '1,160p' "$testdir/late/[email protected]"
# generated unit contents appear here

The suffix is escaped when needed, so a filename with unusual characters may not map to the name you first guess. Trust the path printed by find over your own assumption. This direct test never starts the application.

6. Fix the source and recover cleanly

Change the .desktop file only after deciding whether the application should start in this desktop environment. For a user override, leave the original system file untouched and create or edit the same filename under ~/.config/autostart/. To undo that override, remove the user copy and reload the user manager:

$ rm -- "$HOME/.config/autostart/example.desktop"
$ systemctl --user daemon-reload

That removal is irreversible unless you kept a backup, so copy the file first if it holds useful settings. Do not delete a system-wide file as a shortcut: that needs elevated privileges and affects other users. If the service starts something you did not want running, stop the generated unit for the current session while you investigate:

$ systemctl --user stop [email protected]

Stopping it does not repair the source entry. The next graphical-session start can bring it straight back until the .desktop file is corrected or hidden.

Done means

  • Identified the winning .desktop file by XDG precedence, user over system.
  • Checked the keys that suppress generation or add a condition.
  • Reloaded the user manager and inspected the generated service with systemctl --user cat.
  • Ran a temporary generator test when the normal session did not make the problem obvious.
  • Changed the source entry, not the generated files, and know how to undo a user override.