Troubleshooting
Run padctl doctor first and paste its output in bug reports. It checks the
daemon socket, the systemd service state, kernel driver bindings, and every
supported device in one pass, and prints next-step hints. The manual flows
below remain as fallback when doctor is unavailable or inconclusive.
Common runtime failures that have generated repeat issue reports, with diagnostics and workarounds.
padctl status says it cannot connect to the daemon
Symptoms:
padctl statusexits non-zero or reports that the daemon socket is unreachable.padctl switch <name>cannot apply a mapping.
Check the user service:
systemctl --user status padctl.service
journalctl --user -u padctl.service -n 80
Common causes:
padctl installwas run with--no-enableor--no-start.padctl installwas run as root withoutSUDO_USER, so it could not locate the real user's systemd user manager.- The user has not logged in since install, or headless boot needs linger.
Fix:
systemctl --user daemon-reload
systemctl --user enable --now padctl.service
For headless setups or boot-before-login:
sudo loginctl enable-linger $USER
Permission denied opening hidraw, uinput, or uhid
Symptoms:
- The daemon starts but logs
PermissionDenied,AccessDenied, or open failures for/dev/hidraw*,/dev/uinput, or/dev/uhid. padctl scansees the controller but the daemon cannot manage it.
Fix:
sudo udevadm control --reload-rules
sudo udevadm trigger
systemctl --user restart padctl.service
Then unplug and replug the controller. Graphical sessions normally receive access
through TAG+="uaccess" ACLs. SSH/headless sessions may also need input-group
membership:
sudo usermod -aG input $USER
Log out and back in after changing groups.
Controller is visible but no matching config is found
Symptoms:
padctl scanlists the HID device but says no config matched.- The daemon log says no devices were found in config dirs.
Check installed configs:
padctl doctor resolves the daemon's real device config directories and lists
every device TOML it finds — prefer it over a hardcoded path, because the
install prefix differs by platform (ostree/immutable distros install under
/usr/local/share/padctl/devices, not /usr/share/padctl/devices):
padctl doctor
To inspect a specific config manually, validate it from the directory doctor reported, e.g.:
padctl --validate /usr/share/padctl/devices/sony/dualsense.toml
If doctor finds zero device TOMLs, reinstall the current package. If your device is not listed, capture it and open a device-config contribution.
Kernel driver or another mapper still owns the controller
Symptoms:
- The physical controller continues to appear directly in games while padctl is running.
- padctl cannot exclusively grab the device, or duplicate inputs appear.
- Xbox-compatible devices still bind to
xpadeven though their device TOML setsblock_kernel_drivers.
Package-manager install fix:
systemctl --user daemon-reload
systemctl --user enable --now padctl.service
sudo udevadm control --reload-rules
Then unplug and replug the controller. The driver-block udev rule unbinds the kernel driver only while a padctl daemon is running (its control socket exists), so no extra setup step is needed — and a stopped daemon means the kernel driver keeps the device.
Source install fix:
sudo padctl install
systemctl --user restart padctl.service
Then unplug and replug the controller. For devices with block_kernel_drivers,
the source installer installs the udev rules and also tries to unbind already
attached matching devices during install. Do not use sudo padctl install as
the normal fix for AUR or .deb installs because it rewrites files that the
package manager owns.
padctl install warns "source 'devices/' directory not found"
Symptoms:
padctl installprints a warning about a missingdevices/directory.- After install,
padctl scanor the daemon log reports "no devices found in config dirs". - The daemon starts but no controller is recognized.
Root cause: pre-v0.1.5 .deb packages stripped one directory level from the devices/ tree
during packaging, leaving device TOML files absent from the installed prefix (issue #216).
Fixed in v0.1.5+.
Workaround: upgrade to v0.1.5 or later.
Verify the fix:
dpkg -L padctl | grep 'devices/'
The output should list multiple .toml files under /usr/share/padctl/devices/<vendor>/.
If the list is empty, the old package is still installed — re-download and reinstall.
User service exits with status=218/CAPABILITIES on Ubuntu 26.04 / systemd 257+
Fixed in v0.1.6. If you are running an older release, use the workaround below.
Symptoms:
systemctl --user status padctl.serviceshows:Failed at step CAPABILITIES spawning /usr/bin/padctl: Operation not permitted Main process exited, code=exited, status=218/CAPABILITIES- The daemon never starts;
padctl statusreturnscannot connect to padctl daemon. - The restart counter climbs in
journalctl --user -u padctl.service.
Root cause (pre-v0.1.6): the user service unit declared LockPersonality=true,
ProtectClock=true, and NoNewPrivileges=true. systemd 257+ enforces these options more
strictly on user instances; the kernel rejects the capability adjustments required to apply
them, killing the process before it starts.
Workaround (pre-v0.1.6 only): install a drop-in that clears the three offending directives:
mkdir -p ~/.config/systemd/user/padctl.service.d
cat > ~/.config/systemd/user/padctl.service.d/no-cap-lockdown.conf <<'EOF'
[Service]
LockPersonality=
ProtectClock=
NoNewPrivileges=
EOF
systemctl --user daemon-reload
systemctl --user restart padctl
Assigning an empty value to a systemd directive resets it to the default (unset). The functional and security impact is small: the daemon runs as your user with no privileged operations, so removing these three flags does not expand what it can do.
Reference: issue #216
Build fails on Arch Linux: relocation R_X86_64_PC64 against symbol ...
Symptoms:
zig buildfails during linking:
or similarrelocation R_X86_64_PC64 against symbol '__libc_start_main' can not be used when making a PIE objectR_X86_64_PC64/.sframe section is unsupportederrors.- Affects Arch Linux with glibc 2.43 or later.
Root cause: glibc 2.43+ adds .sframe sections to crt1.o startup objects that Zig 0.15.x's
linker does not handle. This is an upstream Zig limitation, not a padctl bug.
Workaround: build against the musl static target:
zig build -Doptimize=ReleaseSafe -Dtarget=x86_64-linux-musl
The resulting binary is fully static and works on any Linux distribution regardless of glibc version. This is the same target used for official padctl release tarballs.
Alternatively, build inside the canonical Docker image (./scripts/padctl-docker build,
Debian bookworm + glibc 2.36) for a reproducible build environment.
Reference: issue #147