On Linux, onlykey-agent intermittently fails to open the OnlyKey's HID interface with a OSError: open failed error. It then works fine on the next invocation.
The issue can be reliably reproduced when the OnlyKey was just used by another application (e.g. KeePassXC HMAC-SHA1 challenge-response) or after a previous onlykey-agent run was interrupted with CTRL-C.
Environment
Arch Linux, hidapi with the cython backend resolving to libusb (libhidapi-libusb).
$ B=/home/fidel/.local/share/uv/tools/onlykey-agent/lib/python3.13/site-packages
$ ldd "$B/hid.cpython-313-x86_64-linux-gnu.so" | grep -i usb
# uses libusb
libusb-1-150b88da.0.so.0.1.0 => /home/fidel/.local/share/uv/tools/onlykey-agent/lib/python3.13/site-packages/hidapi.libs/libusb-1-150b88da.0.so.0.1.0 (0x00007efee2c00000)
$ ldd "$B/hidraw.cpython-313-x86_64-linux-gnu.so" | grep -i usb
# no libusb
Symptoms
# Do one of these things:
# 1. Open a KeepassXC DB using Onlykey for HMAC
# 2. Run `onlykey-agent` but abort with CTRL-C when seeing the button challenge.
# Then complete the challenge in OnlyKey and try onlykey-agent again.
$ onlykey-agent <identity> -- ssh <server>
ERROR failed to connect [client.py]
Traceback (most recent call last):
File ".../onlykey/client.py", line ..., in _connect
self._hid.open_path(self.path)
File "hid.pyx", line 158, in hid.device.open_path
OSError: open failed
Re-running the exact same command immediately afterward succeeds. Notably, waiting any amount of time does not help, only running the command a second time does.
The problem: libusb-backed hidapi
On my setup, hid.enumerate() returned libusb-style paths and zeroed usage pages:
path=b'1-3:1.2' usage_page=0x0 interface_number=2 ...
The hidraw backend reports:
path=b'/dev/hidraw14' usage_page=0xf1d0 interface_number=2 ...
Running udevadm monitor --udev --subsystem-match=hidraw when using the libusb-backed hidapi shows how the device id increments every time (0026, 0027, 0028...) as libusb detaches/reattaches the kernel driver:
UDEV [6514.362533] remove /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0026/hidraw/hidraw12 (hidraw)
UDEV [6514.478417] add /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0027/hidraw/hidraw12 (hidraw)
UDEV [6515.641427] remove /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0027/hidraw/hidraw12 (hidraw)
UDEV [6515.980519] add /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0028/hidraw/hidraw12 (hidraw)
UDEV [6516.220419] remove /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0028/hidraw/hidraw12 (hidraw)
UDEV [6516.565550] add /devices/pci0000:00/0000:00:02.1/0000:05:00.0/0000:06:0c.0/0000:13:00.0/usb1/1-3/1-3:1.0/0003:1D50:60FC.0029/hidraw/hidraw12 (hidraw)
Fix
Prefer the hidraw backend on Linux, with a fallback to the current hid one. The change is minimal in onlykey/client.py. I will submit a PR with this fix.
The hidraw module exposes the same API, so no other code changes should be needed.
On Linux,
onlykey-agentintermittently fails to open the OnlyKey's HID interface with aOSError: open failederror. It then works fine on the next invocation.The issue can be reliably reproduced when the OnlyKey was just used by another application (e.g. KeePassXC HMAC-SHA1 challenge-response) or after a previous onlykey-agent run was interrupted with CTRL-C.
Environment
Arch Linux,
hidapiwith the cython backend resolving tolibusb(libhidapi-libusb).Symptoms
Re-running the exact same command immediately afterward succeeds. Notably, waiting any amount of time does not help, only running the command a second time does.
The problem: libusb-backed hidapi
On my setup,
hid.enumerate()returnedlibusb-style paths and zeroed usage pages:The
hidrawbackend reports:Running
udevadm monitor --udev --subsystem-match=hidrawwhen using the libusb-backed hidapi shows how the device id increments every time (0026, 0027, 0028...) as libusb detaches/reattaches the kernel driver:Fix
Prefer the
hidrawbackend on Linux, with a fallback to the currenthidone. The change is minimal in onlykey/client.py. I will submit a PR with this fix.The
hidrawmodule exposes the same API, so no other code changes should be needed.