Troubleshooting Guide
This guide covers common issues you might encounter while using FIDO Bridge and how to resolve them.
Quick Troubleshooting
Before diving into specific issues, try these quick diagnostic steps:
1. Run the Diagnostics Tool
The fastest way to identify issues is using the built-in diagnostics command:
fido-bridge diagnose
Source: /path/to/fido-bridge/crates/client/src/commands/install.rs (lines 432-636)
What it checks:
- Service running and enabled status
- D-Bus interface availability (
org.fidobridge.Client) /dev/uhidexists and has correct permissions- ACL permissions for your user
- Configuration file exists
- Binary installation and PATH setup
Example output:
FIDO Bridge Diagnostics
Service Status:
Service running: ✓ Yes
Service enabled: ✓ Yes
D-Bus Interface:
Interface available: ✓ Yes
UHID Device Access:
/dev/uhid exists: ✓ Yes
Permissions: 660
Group: input
UHID ACL permissions: ✓ ACL set for username
Configuration:
Config file: ✓ Exists
Location: /home/username/.config/fido-bridge/config.toml
Binary Installation:
Binary installed: ✓ Yes
Location: /home/username/.local/bin/fido-bridge
In PATH: ✓ Yes
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Status: Service is running normally
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
If the diagnostics show issues, it will provide specific troubleshooting commands.
2. Check Service Status
fido-bridge status
Source: /path/to/fido-bridge/crates/client/src/commands/status.rs
Shows:
- Service state (running/stopped)
- Device ID
- Server configuration
- Number of paired devices
- Active pairing sessions
3. View Recent Logs
fido-bridge logs
Source: /path/to/fido-bridge/crates/client/src/commands/logs.rs
Shows the last 50 log entries. Look for errors or warnings.
General Troubleshooting Steps
If quick diagnostics don't resolve the issue:
-
Enable debug logging:
Linux client:
fido-bridge --verbose daemon
# Or set environment variable:
RUST_LOG=debug fido-bridge daemonAndroid app: Go to Settings → Enable debug mode
-
Check all components are running:
- Linux client is running:
fido-bridge status - Relay server is accessible:
curl http://localhost:3000/health - Android app is open and background service is active
- Linux client is running:
-
Verify pairing:
- Linux:
cat ~/.config/fido-bridge/devices.json | jq - Android: Check paired devices list in app
- Linux:
-
Check logs:
- Linux:
fido-bridge logsorjournalctl --user -u fido-bridge - Android: Logcat (
adb logcat | grep FidoBridge)
- Linux:
Common Issues
Authentication Issues
"No Paired Devices"
Symptom: Authentication fails with "No paired devices available"
Cause: Linux client has no paired Android devices
Solution:
- Complete pairing process (see Pairing Guide)
- Verify pairing file exists:
ls ~/.config/fido-bridge/devices.json - Check file is not empty:
cat ~/.config/fido-bridge/devices.json
"Transaction Timeout"
Symptom: Authentication times out after 4 minutes
Cause: Transaction timed out (240-second default)
Common Reasons:
- User didn't tap YubiKey to Android phone within timeout
- Android app not running or not polling for messages
- Network connectivity issue between Android and server
Solutions:
- Ensure Android app is running and in foreground
- Check notification: Android should show transaction notification
- Tap "Approve" in the app, then tap YubiKey to phone
- Check app is polling:
# View Android logs
adb logcat | grep "Polling for messages" - Reduce timeout (if transactions consistently timeout):
# ~/.config/fido-bridge/config.toml
[timeouts]
transaction_timeout = 120 # 2 minutes instead of 4
"Tag is Out of Date" or "NFC Tag Lost"
Symptom: NFC communication interrupted during authentication
Cause: YubiKey moved away from phone during NFC operation
Solutions:
- Keep YubiKey close to NFC sensor on phone (usually on back, near camera)
- Hold steady for 2-3 seconds until operation completes
- Remove phone case if thick (can interfere with NFC signal)
- Try different position: NFC sensor location varies by phone model
- Wait for vibration/beep: Indicates NFC operation completed successfully
Session Cache Helps:
- First tap establishes ClientPIN session (30-second cache)
- Subsequent operations in same 30s window don't require retapping
"CTAP2 Error: 0x31 (PIN Required)"
Symptom: YubiKey requires PIN but browser doesn't prompt
Cause: ClientPIN flow not completing successfully
Solutions:
- Ensure YubiKey has PIN set:
# Check YubiKey PIN status
ykman fido info - Set PIN if not set:
ykman fido access change-pin - Check session cache is working (30-second TTL):
- First operation should prompt for PIN on YubiKey
- Subsequent operations within 30s should not require PIN
- Clear session cache if stale:
- Wait 30 seconds
- Or restart Android app
"CTAP2 Error: 0x36 (PIN Blocked)"
Symptom: YubiKey PIN is blocked after too many incorrect attempts
Cause: Too many failed PIN attempts (usually 8 attempts)
Solutions:
- Reset YubiKey PIN (requires admin PIN):
ykman fido reset
# WARNING: This erases all FIDO credentials on the YubiKey! - Or unlock with PUK (if set):
ykman fido access unblock-pin - Prevention: Use correct PIN and enable PIN caching
NFC Communication Issues
"NFC Not Available"
Symptom: Android app shows "NFC is not available on this device"
Cause: Device doesn't have NFC hardware or NFC is disabled
Solutions:
- Check device has NFC:
- Go to Android Settings → Connected devices → Connection preferences
- Look for "NFC" option (if absent, device doesn't support NFC)
- Enable NFC:
- Settings → Connected devices → NFC → Toggle ON
- Grant NFC permission to FIDO Bridge app
"NFC Read Error"
Symptom: App detects YubiKey but can't read it
Cause: NFC communication failure (APDU error)
Solutions:
- Clean YubiKey contacts: Wipe with soft cloth
- Remove interference:
- Take phone out of metal case
- Move away from metal surfaces
- Turn off other NFC devices nearby
- Restart Android NFC service:
- Toggle NFC off and on in Android settings
- Or reboot Android device
- Check YubiKey firmware:
ykman info
# Ensure firmware is recent (5.0+)
"APDU Timeout"
Symptom: NFC operation times out after several seconds
Cause: YubiKey not responding to APDU commands
Solutions:
- Ensure YubiKey is genuine (counterfeit keys may not support FIDO2)
- Update YubiKey firmware:
ykman firmware update - Try different NFC antenna position on phone
- Check Android app APDU timeout configuration:
// In app/android/app/src/main/kotlin/.../NfcHandler.kt
val timeout = 5000 // 5 seconds
Connectivity Issues
"Connection Failed: Unable to Reach Server"
Symptom: Android app can't connect to relay server
Cause: Network connectivity or server configuration issue
Solutions:
- Verify server is running:
curl http://localhost:3000/health
# Should return: {"status": "ok"} - Check server URL in Android app:
- Settings → Server URL
- For embedded server: Use Linux machine's LAN IP (e.g.,
http://192.168.1.100:3000) - For remote server: Use public URL (e.g.,
https://relay.example.com)
- Ping server from Android:
- Open browser on Android
- Visit
http://192.168.1.100:3000/health - Should show
{"status": "ok"}
- Check firewall on Linux:
sudo ufw status
sudo ufw allow 3000/tcp - Verify both devices on same network (for embedded server)
"SSL Certificate Verification Failed"
Symptom: Android app rejects server TLS certificate
Cause: Self-signed certificate or certificate mismatch
Solutions:
- Use valid TLS certificate (from Let's Encrypt, etc.)
- For development: Disable cert verification in app (NOT for production):
// app/lib/src/services/api_client.dart
HttpClient()..badCertificateCallback = (cert, host, port) => true; - Install self-signed cert on Android:
- Settings → Security → Install from storage
- Select your .crt file
"Polling Stopped"
Symptom: Android app stops receiving messages
Cause: Background service crashed or was killed by Android
Solutions:
- Check background service status in app Settings
- Disable battery optimization for FIDO Bridge:
- Settings → Apps → FIDO Bridge → Battery → Unrestricted
- Restart app to restart background service
- Check Android logs:
adb logcat | grep "BackgroundService"
Linux Client Issues
"Permission Denied: Cannot Create UHID Device"
Symptom: Client crashes with "Permission denied (os error 13)" or UHID device cannot be created
Cause: Insufficient permissions to access /dev/uhid
Solutions (in order of preference):
-
Run the installer (RECOMMENDED - automatic, secure, persistent):
fido-bridge installSource:
/path/to/fido-bridge/crates/client/src/commands/install.rs(lines 355-430)The installer automatically:
- Grants read/write ACL permissions to
/dev/uhidfor your user only (secure, immediate access) - Installs a udev rule at
/etc/udev/rules.d/99-fido-bridge.rulesto persist permissions across reboots - Reloads udev rules automatically
What the udev rule does (from install.rs lines 395-430):
KERNEL=="uhid", RUN+="/usr/bin/setfacl -m u:username:rw /dev/uhid"On every boot, when the UHID kernel module loads, the rule automatically sets ACL permissions for your user.
- Grants read/write ACL permissions to
-
Use ACL manually (immediate access, requires manual udev rule for persistence):
# Grant access to current user only (secure, immediate, but lost on reboot)
sudo setfacl -m u:$USER:rw /dev/uhid
# Verify ACL is set
getfacl /dev/uhid | grep "user:$USER"This works immediately and is secure (only your user gets access), but permissions are lost on reboot unless you create a udev rule (see installer method above).
-
Run diagnostics to check current UHID access:
fido-bridge diagnoseThis will show:
- If
/dev/uhidexists - Current permissions and group
- Whether your user has ACL permissions
- Fix suggestions if access is denied
- If
What NOT to do:
- DO NOT use
sudo usermod -a -G input $USER- This grants access to ALL input devices (security risk) - DO NOT use
chmod 666 /dev/uhid- This makes the device world-writable, allowing any process to create fake keyboards/mice and potentially compromise your system
Note: The fido-bridge install method is the most secure and convenient approach. It uses ACL (Access Control Lists) to grant permissions to ONLY your user, and creates a udev rule to make this persistent across reboots.
"UHID Device Not Detected by Browser"
Symptom: Browser doesn't see virtual FIDO device
Cause: UHID device wasn't created or isn't recognized
Solutions:
-
Check UHID device exists:
ls -l /dev/hidraw*
# Should show recently created device -
Verify browser supports WebAuthn:
- Chrome/Chromium 67+
- Firefox 60+
- Navigate to
chrome://flags/#enable-web-authentication-api
-
Check UHID permissions (verify service can access UHID):
# Use diagnostics tool to check all permissions
fido-bridge diagnose
# Or check ACL permissions manually
getfacl /dev/uhid
# Verify you have access
test -r /dev/uhid && test -w /dev/uhid && echo "Access OK" || echo "Access DENIED"If access is denied, the easiest fix is to run the installer which sets up ACL permissions and udev rules:
fido-bridge installSee the "Permission Denied: Cannot Create UHID Device" section above for more details and alternative solutions.
-
Restart browser after starting FIDO Bridge client
-
Load UHID kernel module (if not loaded):
sudo modprobe uhid -
Check service logs for errors:
journalctl --user -u fido-bridge -n 50
"Client Crashes on Startup"
Symptom: Client exits immediately after launch
Cause: Various (check logs for specifics)
Common Causes & Solutions:
- Missing shared libraries:
ldd ./target/release/fido-bridge
# Check for "not found" entries
sudo apt install libssl3 # or equivalent - Corrupted configuration:
mv ~/.config/fido-bridge/config.toml ~/.config/fido-bridge/config.toml.bak
# Restart client (will use defaults) - Corrupted paired devices:
mv ~/.config/fido-bridge/devices.json ~/.config/fido-bridge/devices.json.bak
# Restart client, then re-pair
Pairing Issues
For pairing-specific issues, see the Pairing Guide - Troubleshooting section.
Advanced Debugging
Enable Verbose Logging
Linux Client:
RUST_LOG=trace sudo ./target/release/fido-bridge daemon
This will show:
- All CTAP2 messages (request/response)
- Encryption/decryption operations
- Network communication
- Transaction state transitions
Android App:
- Enable Developer Mode in Android settings
- In FIDO Bridge app: Settings → Debug → Enable verbose logging
- View logs:
adb logcat -s FidoBridge:V
Inspect Network Traffic
Capture relay server traffic:
# On server machine
sudo tcpdump -i any port 3000 -A
Look for:
- HTTP POST/GET requests
- Encrypted message blobs (should be opaque)
- Error responses from server
Analyze CTAP2 Messages
Enable CBOR decoding:
# Install cbor2 Python package
pip install cbor2
# Decode CTAP2 messages from logs
echo "base64_encoded_cbor_here" | base64 -d | python -m cbor2.tool
Test YubiKey Directly
Verify YubiKey works outside FIDO Bridge:
# Install ykman
pip install yubikey-manager
# Test FIDO2 functionality
ykman fido info
# Test WebAuthn on a test site
# Visit: https://webauthn.io/
If YubiKey works directly but not through FIDO Bridge, the issue is in FIDO Bridge.
Check Transaction State
View active transactions (Linux client debug mode):
# In interactive mode, press 'T' to show transactions
# Or check logs:
grep "Transaction" /var/log/fido-bridge/client.log
Look for:
- Expired transactions (not cleaned up)
- Stuck in "AwaitingGetInfo" state
- Mismatched transaction IDs
Memory/Resource Issues
Check resource usage:
# Linux client
ps aux | grep client
top -p $(pgrep client)
# Android app
adb shell dumpsys meminfo com.example.fido_bridge
High memory usage?
- Transaction cache not being cleaned up
- Message queue growing unbounded
- Possible memory leak (report bug!)
Getting Help
If you're still stuck after trying these solutions:
Gather Debug Information
-
Linux client logs (with debug enabled):
FIDO_BRIDGE_LOG_LEVEL=debug sudo ./target/release/fido-bridge daemon > client.log 2>&1 -
Android app logs:
adb logcat > android.log -
System information:
uname -a # Linux kernel version
ykman info # YubiKey info
flutter doctor # Flutter environment -
Configuration files:
cat ~/.config/fido-bridge/config.toml
cat ~/.config/fido-bridge/devices.json | jq
Report a Bug
Open an issue on GitHub: https://github.com/0xC9C3/fido-bridge/issues
Include:
- Description of the issue
- Steps to reproduce
- Expected vs. actual behavior
- Debug logs (sanitize any secrets!)
- System information
- FIDO Bridge version
Known Issues
Issue: Browser Extension Conflicts
Symptom: WebAuthn prompts appear twice (once from FIDO Bridge, once from extension)
Cause: Password manager browser extension interfering
Workaround: Disable WebAuthn in password manager extension settings
Issue: Slow First Authentication
Symptom: First WebAuthn authentication after pairing takes 10-20 seconds
Cause: ClientPIN key agreement establishment + NFC communication overhead
Expected Behavior: Subsequent authentications within 30 seconds are faster (session cache)
Issue: Multiple Paired Devices Race Condition
Symptom: Wrong device responds to WebAuthn request
Cause: All paired devices receive request, first to respond wins
Workaround: Unpair devices you're not actively using
Future Fix: Device selection UI (planned feature)
Performance Optimization
Reduce Latency
- Use local relay server (embedded mode) instead of remote
- Reduce polling interval (at cost of higher CPU usage):
[timeouts]
poll_interval_ms = 100 # Default: 250 - Keep Android app in foreground (background polling is slower)
Reduce Battery Usage (Android)
- Increase background poll interval:
// app/lib/src/services/background_service.dart
const backgroundPollInterval = Duration(seconds: 10); // Default: 5 - Disable background service when not actively using FIDO Bridge
- Only pair with one Linux client (reduces message processing)
Next Steps
- Architecture Overview - Understand system design
- Protocol Documentation - Deep dive into CTAP2 and message formats
- Contributing - Report bugs or contribute fixes