TL;DR
This post explains why homectl-managed home directories behave differently from traditional ones, why environment variables may be missing when a user logs in remotely, and how lingerd and PAM interact. It provides a stable configuration that allows SSH logins without requiring a local login first, while keeping environment initialization consistent.
Introduction
After using homectl on Linux for a while, I noticed thumbnails were no longer working.
It was also impossible to change or keep some of the user system settings, like the sound settings.
Investigating this led me into multiple rabbit-holes and dead ends.
Eventually I made the suggestion of homectl being involded to an LLM and it then was able to point me in the right direction of where to look and how to solve this.
Once my system seemed stable and showing thumbnails again, I asked the LLM to help writing up on its findings.
Using homectl With SSH: Understanding Linger, PAM, and Environment Setup
Systemd’s homectl can provide encrypted, automatically mounted home directories with clean integration into user sessions. However, when using homectl on a workstation that also accepts SSH logins, you may run into surprising behavior:
- Environment variables like
XDG_DATA_DIRSfail to load over SSH. - The home directory doesn’t mount until a graphical login happens.
- Enabling
lingersolves one problem but introduces others.
This post explains why these issues occur and presents a configuration that works reliably.
Why homectl Behaves Differently
When using systemd-homed, your home directory is not simply a static filesystem entry. Instead, systemd:
- Authenticates the user via systemd-homed (using JSON metadata).
- Mounts the home directory via a systemd-generated
home-*mount unit. - Applies user-side identity mapping (idmap + fs encryption).
- Starts a systemd user manager when a login session opens.
This means your home directory only exists after systemd-homed is invoked, and that depends on how you log in.
The Role of Linger
loginctl enable-linger USER keeps the user’s systemd instance running even when no sessions are active. This guarantees:
- The home directory auto-mounts early in the boot process.
- Systemd user services start without needing a login.
- SSH sessions have access to the home directory.
However, lingering also means:
- The system starts the user manager at boot.
- PAM environment logic may not run for the first session, leading to missing variables.
- Some XDG initialization that assumes an interactive login may not trigger.
In short: linger trades “always available” for “environment not completely initialized unless handled manually”.
Why Your Environment Variables Were Missing
When logging in via SSH with lingering enabled, the user manager may already be running before PAM sets up the environment. This means:
systemd --userstarts with a minimal environment.- Later SSH sessions inherit environment variables from PAM only, but systemd user services do not.
- Graphical sessions add another layer of environment configuration, which can mask the issue.
This is why disabling linger can make your environment correct — PAM initializes everything before the user manager starts — but then the home directory would not be available via SSH.
A Reliable Configuration
The working compromise is:
- Keep Linger Enabled so that SSH works and the home directory mounts.
- Explicitly set needed environment variables in:
/etc/environmentfor system-wide values, or$HOME/.config/environment.d/*.conffor homed-specific, user-level environment.
This ensures both:
- systemd user manager gets the correct environment at boot, and
- all login methods (SSH, TTY, Wayland) behave consistently.
Example: create
1~/.config/environment.d/xdg.conf
with:
1XDG_DATA_DIRS=$/home/$USER/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
Systemd will import this into the user manager before it starts, solving the mismatch.
Verifying the Result
1systemctl --user show-environment | grep XDG
should show the same values as:
1env | grep XDG
Regardless of:
- graphical login
- SSH login
- lingering
Caveat: Don’t use static mount units with systemd-homed
When using systemd-homed, the home directory must not be mounted using:
/etc/fstab- a persistent
/etc/systemd/system/home-$USER.mountunit systemctl enable home-$USER.mount
systemd-homed creates its own transient home-USER.mount unit under
/run/systemd/transient/ and manages the ordering internally.
If a static mount unit exists, systemd tries to mount the home directory during early boot, before systemd-homed is ready. This leads to:
- long boot delays (typically ~90 seconds)
- XDG directories being mis-set (
//.cache,//.local/share) - services like
xfconfdfailing
If you previously experimented with manual mounting or fstab, ensure that /etc/systemd/system/home-USER.mount does not exist.
If it does:
1sudo rm /etc/systemd/system/home-USER.mount
2sudo systemctl daemon-reload
This restores proper homed behavior and eliminates the boot timeout.
Conclusion
systemd-homed is powerful, but it deviates from traditional UNIX assumptions. Understanding how user sessions, PAM, and the user manager interact makes it much easier to create predictable behavior.
By enabling lingering for availability and defining environment variables using environment.d, you get the best of both worlds:
- SSH works before graphical login
- home directory auto-mounts
- environment is correct and consistent
More work than /etc/passwd, but also more flexibility.
Appendix
Check if linger is enabled
1loginctl show-user $USER | grep Linger
Check home mount status
1systemctl status home-$USER.mount
Inspect user manager environment
1systemctl --user show-environment