Skip to main content

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/uhid exists 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:

  1. Enable debug logging:

    Linux client:

    fido-bridge --verbose daemon
    # Or set environment variable:
    RUST_LOG=debug fido-bridge daemon

    Android app: Go to Settings → Enable debug mode

  2. 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
  3. Verify pairing:

    • Linux: cat ~/.config/fido-bridge/devices.json | jq
    • Android: Check paired devices list in app
  4. Check logs:

    • Linux: fido-bridge logs or journalctl --user -u fido-bridge
    • Android: Logcat (adb logcat | grep FidoBridge)

Common Issues

Authentication Issues

"No Paired Devices"

Symptom: Authentication fails with "No paired devices available"

Cause: Linux client has no paired Android devices

Solution:

  1. Complete pairing process (see Pairing Guide)
  2. Verify pairing file exists: ls ~/.config/fido-bridge/devices.json
  3. 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:

  1. Ensure Android app is running and in foreground
  2. Check notification: Android should show transaction notification
  3. Tap "Approve" in the app, then tap YubiKey to phone
  4. Check app is polling:
    # View Android logs
    adb logcat | grep "Polling for messages"
  5. 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:

  1. Keep YubiKey close to NFC sensor on phone (usually on back, near camera)
  2. Hold steady for 2-3 seconds until operation completes
  3. Remove phone case if thick (can interfere with NFC signal)
  4. Try different position: NFC sensor location varies by phone model
  5. 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:

  1. Ensure YubiKey has PIN set:
    # Check YubiKey PIN status
    ykman fido info
  2. Set PIN if not set:
    ykman fido access change-pin
  3. Check session cache is working (30-second TTL):
    • First operation should prompt for PIN on YubiKey
    • Subsequent operations within 30s should not require PIN
  4. 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:

  1. Reset YubiKey PIN (requires admin PIN):
    ykman fido reset
    # WARNING: This erases all FIDO credentials on the YubiKey!
  2. Or unlock with PUK (if set):
    ykman fido access unblock-pin
  3. 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:

  1. Check device has NFC:
    • Go to Android Settings → Connected devices → Connection preferences
    • Look for "NFC" option (if absent, device doesn't support NFC)
  2. Enable NFC:
    • Settings → Connected devices → NFC → Toggle ON
  3. 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:

  1. Clean YubiKey contacts: Wipe with soft cloth
  2. Remove interference:
    • Take phone out of metal case
    • Move away from metal surfaces
    • Turn off other NFC devices nearby
  3. Restart Android NFC service:
    • Toggle NFC off and on in Android settings
    • Or reboot Android device
  4. 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:

  1. Ensure YubiKey is genuine (counterfeit keys may not support FIDO2)
  2. Update YubiKey firmware:
    ykman firmware update
  3. Try different NFC antenna position on phone
  4. 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:

  1. Verify server is running:
    curl http://localhost:3000/health
    # Should return: {"status": "ok"}
  2. 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)
  3. Ping server from Android:
    • Open browser on Android
    • Visit http://192.168.1.100:3000/health
    • Should show {"status": "ok"}
  4. Check firewall on Linux:
    sudo ufw status
    sudo ufw allow 3000/tcp
  5. 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:

  1. Use valid TLS certificate (from Let's Encrypt, etc.)
  2. For development: Disable cert verification in app (NOT for production):
    // app/lib/src/services/api_client.dart
    HttpClient()..badCertificateCallback = (cert, host, port) => true;
  3. 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:

  1. Check background service status in app Settings
  2. Disable battery optimization for FIDO Bridge:
    • Settings → Apps → FIDO Bridge → Battery → Unrestricted
  3. Restart app to restart background service
  4. 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):

  1. Run the installer (RECOMMENDED - automatic, secure, persistent):

    fido-bridge install

    Source: /path/to/fido-bridge/crates/client/src/commands/install.rs (lines 355-430)

    The installer automatically:

    • Grants read/write ACL permissions to /dev/uhid for your user only (secure, immediate access)
    • Installs a udev rule at /etc/udev/rules.d/99-fido-bridge.rules to 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.

  2. 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).

  3. Run diagnostics to check current UHID access:

    fido-bridge diagnose

    This will show:

    • If /dev/uhid exists
    • Current permissions and group
    • Whether your user has ACL permissions
    • Fix suggestions if access is denied

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:

  1. Check UHID device exists:

    ls -l /dev/hidraw*
    # Should show recently created device
  2. Verify browser supports WebAuthn:

    • Chrome/Chromium 67+
    • Firefox 60+
    • Navigate to chrome://flags/#enable-web-authentication-api
  3. 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 install

    See the "Permission Denied: Cannot Create UHID Device" section above for more details and alternative solutions.

  4. Restart browser after starting FIDO Bridge client

  5. Load UHID kernel module (if not loaded):

    sudo modprobe uhid
  6. 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:

  1. Missing shared libraries:
    ldd ./target/release/fido-bridge
    # Check for "not found" entries
    sudo apt install libssl3 # or equivalent
  2. Corrupted configuration:
    mv ~/.config/fido-bridge/config.toml ~/.config/fido-bridge/config.toml.bak
    # Restart client (will use defaults)
  3. 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:

  1. Enable Developer Mode in Android settings
  2. In FIDO Bridge app: Settings → Debug → Enable verbose logging
  3. 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

  1. Linux client logs (with debug enabled):

    FIDO_BRIDGE_LOG_LEVEL=debug sudo ./target/release/fido-bridge daemon > client.log 2>&1
  2. Android app logs:

    adb logcat > android.log
  3. System information:

    uname -a  # Linux kernel version
    ykman info # YubiKey info
    flutter doctor # Flutter environment
  4. 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

  1. Use local relay server (embedded mode) instead of remote
  2. Reduce polling interval (at cost of higher CPU usage):
    [timeouts]
    poll_interval_ms = 100 # Default: 250
  3. Keep Android app in foreground (background polling is slower)

Reduce Battery Usage (Android)

  1. Increase background poll interval:
    // app/lib/src/services/background_service.dart
    const backgroundPollInterval = Duration(seconds: 10); // Default: 5
  2. Disable background service when not actively using FIDO Bridge
  3. Only pair with one Linux client (reduces message processing)

Next Steps