Skip to content

fix: use user domain instead of gui for hm sops-nix launchd agent#966

Open
Eason20000 wants to merge 1 commit into
Mic92:masterfrom
Eason20000:hm-launchd-user-domain
Open

fix: use user domain instead of gui for hm sops-nix launchd agent#966
Eason20000 wants to merge 1 commit into
Mic92:masterfrom
Eason20000:hm-launchd-user-domain

Conversation

@Eason20000

Copy link
Copy Markdown

Problem

Home Manager sops-nix fails to activate on headless macOS servers. The activation script runs:

launchctl bootstrap gui/$(id -u) ...

which fails with:

Bootstrap failed: 125: Domain does not support specified action

The gui/UID domain only exists when the user has an Aqua (GUI) login session. Machines accessed exclusively via SSH (headless Mac Mini, EC2 Mac instances, CI build servers) never create this domain.

Root cause

Two issues in modules/home-manager/sops.nix:

  1. Activation script hardcodes gui/$(id -u …)gui/UID domain requires an Aqua session
  2. LaunchAgent plist omits LimitLoadToSessionType — defaults to Aqua, which maps to gui/UID

Fix

The user/UID domain exists after any login — GUI or SSH (pam_launchd.so creates it). Background agents loaded into this domain do not require a graphical session.

Two-line change:

  1. Set LimitLoadToSessionType = "Background" in the LaunchAgent plist so the agent is loadable into user/UID
  2. Change activation script domain target from gui/ to user/

Evidence

Home Manager's own launchd module (link) already supports this distinction:

launchd.agents.<name>.domain — The launchd domain to bootstrap this agent into.
The gui domain is appropriate for agents that need the user's Aqua session.
The user domain is appropriate for background services that do not require a graphical login session.

Apple's launchd.plist(5) man page (shipped with every macOS release) defines four session types:

  • Aqua — requires GUI login (maps to gui/UID)
  • Background — per-user context, parent of all sessions for a user (maps to user/UID)
  • StandardIO — non-GUI login sessions (SSH per-session)
  • LoginWindow — pre-login context

StackOverflow confirmation (link):

The user domain is available after a login (such as through SSH), but to add a service to this domain your .plist must contain LimitLoadToSessionType = Background.

Verified

macOS machine session type before after
MacBook (GUI login) gui/501 + user/501 works works
Mac Mini M4 (SSH only) user/501 only 125: Domain does not support works

The Background session type covers both use cases — a single session type suffices without needing an array.

@Eason20000
Eason20000 force-pushed the hm-launchd-user-domain branch from 1a4f684 to dc278a6 Compare July 10, 2026 11:45
Using gui/UID domain requires an Aqua GUI session, which is
unavailable on headless macOS servers. The user/UID domain is
available after any login (SSH or GUI) and works with the
Background session type.

- Set LimitLoadToSessionType = "Background" in the agent plist
- Change activation script domain-target from gui/ to user/
@Eason20000
Eason20000 force-pushed the hm-launchd-user-domain branch from dc278a6 to 91c125e Compare July 10, 2026 12:07
@Eason20000
Eason20000 marked this pull request as draft July 10, 2026 12:22
@Eason20000
Eason20000 marked this pull request as ready for review July 10, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant