Introduction
Udev rules automate device management on Linux by responding to kernel uevents. When a udev rule fails to trigger for a USB device, automated tasks like mounting, permission changes, or script execution do not happen. This affects USB dongles, external drives, serial adapters, and custom hardware that rely on udev for plug-and-play behavior.
Symptoms
- USB device detected by kernel (
dmesgshows new device) but udev rule does not fire - Custom permissions or symlinks not created for the device
- Scripts assigned via
RUN+=never execute - Device appears in
lsusbbut has default root-only permissions udevadm monitorshows the event but your rule does not match
Common Causes
- Incorrect attribute matching (wrong
ATTRS{}orENV{}values) - Rule file placed in wrong directory or missing
.rulesextension - Rule priority/ordering issue: a more generic rule matches first
- Missing
udevadm control --reload-rulesafter rule changes RUN+=script path not absolute or script not executable- Device subsystem mismatch (e.g., matching
usbinstead ofttyfor serial devices)
Step-by-Step Fix
- 1.Verify kernel detects the USB device:
- 2.```bash
- 3.dmesg | tail -20
- 4.lsusb
- 5.ls -la /dev/ttyUSB* 2>/dev/null
- 6.
` - 7.Monitor udev events in real time:
- 8.```bash
- 9.sudo udevadm monitor --environment --udev
- 10.# Then plug in the device and observe the output
- 11.
` - 12.Get complete device attributes for rule writing:
- 13.```bash
- 14.udevadm info --attribute-walk --name=/dev/ttyUSB0
- 15.# or using the device path:
- 16.udevadm info --attribute-walk --path=$(udevadm info --query=path --name=/dev/ttyUSB0)
- 17.
` - 18.Test rule matching without applying:
- 19.```bash
- 20.sudo udevadm test /sys/class/tty/ttyUSB0 2>&1 | grep -E "matching|rule"
- 21.
` - 22.Fix the rule file and reload:
- 23.```bash
- 24.sudo nano /etc/udev/rules.d/99-myusb.rules
- 25.# Ensure correct syntax, absolute paths, and proper subsystem matching
- 26.sudo udevadm control --reload-rules
- 27.sudo udevadm trigger
- 28.
` - 29.Verify rule execution and debug script output:
- 30.```bash
- 31.# Log script output for debugging
- 32.RUN+='/bin/sh -c "echo udev triggered >> /tmp/udev-debug.log"'
- 33.# Check journal for udev events
- 34.journalctl -u systemd-udevd --since "5 min ago"
- 35.
`
Prevention
- Use
udevadm info --attribute-walkto get exact attribute values, never guess - Name rule files with a numeric prefix (e.g.,
99-custom.rules) to control ordering - Always use absolute paths in
RUN+=directives - Test rules with
udevadm testbefore deploying to production - Log udev script output to a file for post-mortem debugging
- Keep rules simple; chain complex logic through a wrapper script