#2792·espanso

Shipped espanso.service uses WantedBy=default.target, racing the display server at boot (worker panics 101 until X/compositor is up)

Author: HaleTomCreated Sep 4, 2026Updated Sep 4, 2026

Description

The shipped systemd user unit (packaging/linux/usr/lib/systemd/user/espanso.service, installed as /usr/lib/systemd/user/espanso.service) is hooked to WantedBy=default.target:

ini
[Unit]
Description=espanso

[Service]
ExecStart=/usr/bin/espanso launcher
Restart=on-failure
RestartSec=3

[Install]
WantedBy=default.target

default.target is reached before the graphical session. On X11 systems espanso talks to Xorg/XWayland via XOpenDisplay, so when the unit starts at boot it races the display server. If X isn't up yet, the worker panics (failed to initialize detector module: detection source initialization failed, espanso/src/cli/worker/engine/mod.rs:146) → daemon exits → launcher panics (espanso/src/cli/launcher/mod.rs:196) → main process exits with status 101 → Restart=on-failure cycles the whole unit every 3 seconds until the display appears. Journal from one boot (4 attempts, ~507ms each):

14:27:30 Started espanso.
14:27:31 [worker(2564)] using X11Source
14:27:31 [worker(2564)] thread 'engine thread' panicked at 'failed to initialize detector module: detection source initialization failed': espanso/src/cli/worker/engine/mod.rs:146
14:27:31 systemd: Main process exited, code=exited, status=101/n/a
14:27:34 restart → same panic
14:27:38 restart → same panic
14:27:41 restart → OK (display finally up)

On AppImage installs this restart cycle has an extra cost: each failed start leaves a dead FUSE mount at /tmp/.mount_espans* (see #2791 for that mechanism).

The fix is one line in the unit: WantedBy=graphical-session.target (plus After=graphical-session.target in [Unit]), so the unit starts with — and after — the graphical session instead of racing it.

Steps to reproduce

  1. X11 system, espanso installed with the shipped espanso.service (as the .deb/AppImage packaging and Arch AUR packages do), WantedBy=default.target.
  2. systemctl --user enable espanso and boot the machine.
  3. If the display server takes more than ~a second to come up after default.target, the unit panics and restarts 2–4 times (journalctl --user -u espanso shows status=101 cycles with failed to initialize detector module).

Expected behavior

espanso should start with the graphical session, not race it: the unit should be wanted by graphical-session.target so XOpenDisplay/compositor connection succeeds on first start.

Screenshots

No screenshot captured.

Logs

Journal excerpt quoted above (full chain visible: using X11Source → engine-thread panic at espanso/src/cli/worker/engine/mod.rs:146 → daemon/launcher 101 → systemd restart).

Your environment

  • Public source code: https://github.com/espanso/espanso (v2.4.0)
  • Environment name and version (e.g., Rust 1.59.0): N/A (AppImage edition; unit file verified from both the shipped packaging and the installed system)
  • Operating system and version (e.g., Ubuntu 20.04.2 LTS): Arch-based (Manjaro v26.1.1, kernel 6.18, systemd 261)
  • Espanso version (e.g., 2.1.4-beta): 2.4.0 (espanso-x11-bin AUR, AppImage)

Self-service

  • I'd be willing to fix this bug myself.