Fixing “Failed to get D-Bus connection: permission denied” for systemctl –user in RHEL 7.4 with SELinux


1 views

When setting up user-level services on RHEL 7.4 with systemd 219, many developers encounter the frustrating error:

Failed to get D-bus connection: permission denied

This typically occurs after progressing from the initial "connection refused" state, indicating partial but incomplete configuration.

For user-level services to work properly, several components must be correctly configured:

# Essential first step
loginctl enable-linger userservice

Two fundamental unit files must exist in /usr/lib/systemd/user/:

dbus.service

[Unit]
Description=D-Bus User Message Bus
Requires=dbus.socket

[Service]
ExecStart=/usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation
ExecReload=/usr/bin/dbus-send --print-reply --session --type=method_call --dest=org.freedesktop.DBus / org.freedesktop.DBus.ReloadConfig

[Install]
Also=dbus.socket

dbus.socket

[Unit]
Description=D-Bus User Message Bus Socket

[Socket]
ListenStream=%t/bus
ExecStartPost=-/bin/systemctl --user set-environment DBUS_SESSION_BUS_ADDRESS=unix:path=%t/bus

[Install]
WantedBy=sockets.target
Also=dbus.service

Your user service should be properly defined in ~/.config/systemd/user/:

[Unit]
Description=Test user-level service

[Service]
Type=dbus
BusName=com.wtf.service
ExecStart=/home/userservice/userservice.py
Restart=on-failure

[Install]
WantedBy=default.target

Adding this to your .bashrc is often necessary:

export XDG_RUNTIME_DIR=/run/user/$(id -u)

After setting this, you might encounter a different error:

Failed to get D-Bus connection: no such file or directory

On RHEL systems with SELinux enabled, additional context settings might be required:

# Check current context
ls -Z /run/user/$(id -u)/bus

# If needed, apply proper context
chcon -t user_tmp_t /run/user/$(id -u)/bus

To confirm your configuration is working:

# Verify lingering is enabled
loginctl show-user userservice | grep Linger

# Check dbus socket activation
systemctl --user list-sockets

# Validate environment variables
systemctl --user show-environment | grep DBUS

Follow this diagnostic sequence when encountering issues:

  1. Verify XDG_RUNTIME_DIR is set correctly
  2. Check socket file exists at /run/user/$(id -u)/bus
  3. Confirm proper permissions on the socket file
  4. Ensure SELinux context is appropriate
  5. Validate DBus service is properly activated

Remember that changes to systemd user units often require a full logout/login cycle rather than just restarting the service.


When working with user-level services in Linux, the systemctl --user command often throws the frustrating "Failed to get D-bus connection: permission denied" error. This typically occurs when the user's D-Bus instance isn't properly initialized or when permissions aren't correctly set.

Before diving into solutions, verify these fundamental requirements:

# Check if linger is enabled for the user
loginctl show-user userservice | grep Linger

# Verify XDG_RUNTIME_DIR is set
echo $XDG_RUNTIME_DIR
# Should output something like /run/user/1000

Here's a comprehensive solution that addresses all potential causes:

# 1. Enable linger for the user
sudo loginctl enable-linger $(whoami)

# 2. Export essential variables
echo "export XDG_RUNTIME_DIR=/run/user/$(id -u)" >> ~/.bashrc
source ~/.bashrc

# 3. Verify socket creation
ls -la $XDG_RUNTIME_DIR/bus

# 4. Restart the user service manager
systemctl --user daemon-reload

# 5. Check if dbus services are running
systemctl --user list-units --type=service | grep dbus

If you're on RHEL/CentOS with SELinux, check these additional steps:

# Check SELinux context
ls -Z $XDG_RUNTIME_DIR/bus

# Temporarily set SELinux to permissive mode for testing
sudo setenforce 0
# Try your command again
# If it works, you'll need to create proper SELinux policies
sudo setenforce 1

Here's an improved version of your service file with better reliability:

[Unit]
Description=Enhanced User Service Example
After=dbus.socket
Wants=dbus.socket

[Service]
Type=dbus
BusName=com.example.service
ExecStart=/home/%u/service.py
Restart=always
RestartSec=5s
Environment="DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/%U/bus"

[Install]
WantedBy=default.target

After implementing the fixes, verify everything works:

# Check service status
systemctl --user status your-service.service

# Check D-Bus connectivity
dbus-send --session --dest=org.freedesktop.DBus \
          --type=method_call --print-reply \
          /org/freedesktop/DBus org.freedesktop.DBus.ListNames