How to Set Up Bluetooth on Fedora (Pairing Devices, Troubleshooting)

Start the Bluetooth service on Fedora and pair devices using the bluetoothctl command-line interface.

The radio is silent until you tell it to listen

You just unboxed a new wireless headset or pulled out a Bluetooth mouse. The GNOME settings panel shows a spinning wheel, or the device list stays stubbornly empty. You open a terminal because the GUI is unresponsive, but bluetoothctl drops you into a prompt that expects commands you have never seen. The hardware switch is on, the kernel sees the adapter, yet nothing connects.

What is actually happening under the hood

Bluetooth on Fedora is not a single application. It is a layered stack. The kernel driver talks to the physical radio chip. The bluez daemon translates those low-level signals into a protocol the desktop environment understands. bluetoothctl is merely a command-line remote control for that daemon. When pairing stalls, the radio is usually powered down at the daemon level, the adapter is blocked by a hardware switch, or the target device is not broadcasting its identity.

Think of the stack like a broadcast tower. The kernel is the steel structure. bluez is the broadcast engineer. bluetoothctl is the walkie-talkie you use to give the engineer orders. If the engineer is asleep, your walkie-talkie does nothing. You must wake the daemon, power the radio, and tell the tower to listen for incoming signals.

The desktop environment communicates with bluez over D-Bus. The system bus handles service management, while the session bus handles user-level pairing requests. Running bluetoothctl as root breaks the session bus connection. The GUI will stop seeing your devices, and audio routing will fail. Always run the tool as your normal user.

Check the daemon state before you type pairing commands. A dead service swallows every command silently.

Start the daemon and power the adapter

The Bluetooth service ships disabled on minimal installs and sometimes fails to start automatically after a kernel update. Check its state before typing any pairing commands.

systemctl status bluetooth
# Verify the daemon is active and not masked
# Look for "Active: active (running)" in the output
# If it says inactive or dead, the daemon needs to be started

If the service is stopped, start it and enable it for future boots. Enabling creates a symlink in the systemd unit directory so the service survives reboots.

sudo systemctl start bluetooth
# Launch the bluez daemon immediately
sudo systemctl enable bluetooth
# Register the service to start automatically on boot

Run systemctl status bluetooth again. If it still fails, check the journal for dependency errors. The daemon often refuses to start if the dbus service is down or if a conflicting rfkill block is active. Fedora follows the convention of keeping user-modified configuration in /etc/bluetooth/ while package-managed files live in /usr/lib/bluetooth/. Never edit files in /usr/lib/. Your changes will vanish on the next dnf upgrade.

Check the daemon state before you type pairing commands. A dead service swallows every command silently.

Pair and connect with bluetoothctl

Once the daemon is running, drop into the interactive controller. This tool does not run as root. Running it with sudo breaks the D-Bus session and prevents the GUI from seeing the connection.

bluetoothctl
# Open the interactive bluez control shell
# You will see a "[bluetooth]#" prompt

The adapter starts in a low-power state. Turn it on and set it to accept incoming pair requests.

power on
# Wake the radio hardware through the daemon
pairable on
# Allow the adapter to accept pairing requests from other devices
agent on
# Enable the interactive agent to handle PIN prompts and confirmations
default-agent
# Register this agent as the primary handler for pairing events

Start scanning. The output lists MAC addresses and device names. Keep the scan running until you spot your device.

scan on
# Begin broadcasting discovery requests to nearby Bluetooth radios
# Wait for your device to appear in the terminal output
scan off
# Stop scanning to conserve battery and reduce radio noise

Initiate the handshake. Replace the placeholder with the actual MAC address from the scan output.

pair 00:11:22:33:44:55
# Request a security handshake with the target device
# Follow any on-screen prompts for PIN codes or passkeys
trust 00:11:22:33:44:55
# Mark the device as trusted so it auto-connects on boot
connect 00:11:22:33:44:55
# Establish the active data link for audio or input
exit
# Return to the standard shell

The trust command and the connect command serve different purposes. trust tells the daemon to remember the device across reboots and to initiate the link automatically when the radio powers up. connect forces an immediate link. Without trust, Fedora will forget the link the moment you suspend or reboot.

Trust the device before you walk away. Without the trust flag, Fedora will forget the link the moment you suspend or reboot.

Verify the connection and audio routing

The terminal does not always confirm success with a clear message. Check the device profile to confirm the link is active and the correct audio or input profile is loaded.

bluetoothctl info 00:11:22:33:44:55
# Display the current connection state and active profiles
# Look for "Connected: yes" and "Trusted: yes"
# Verify the profile matches your hardware (A2DP for audio, HID for keyboards)

If the profile shows HSP/HFP instead of A2DP on a headset, audio will sound like a telephone. Fedora routes Bluetooth audio through PipeWire. The daemon sometimes picks the low-bandwidth profile to allow microphone input. Switch profiles manually if the daemon picks the wrong one.

select-profile a2dp
# Force the high-fidelity audio profile for headsets and speakers
# This disables the microphone but restores stereo quality

Run pactl info to confirm PipeWire recognizes the Bluetooth sink. The output will list the active profile and sample rate. If PipeWire shows off or unavailable, the audio server lost contact with the Bluetooth stack. Restart the PipeWire session with systemctl --user restart pipewire pipewire-pulse.

Run the info command before you assume failure. The link is often up, but the wrong profile is active.

Common pitfalls and error messages

Bluetooth failures usually fall into three categories. Hardware blocks, daemon conflicts, and profile mismatches. Recognize the exact error string to skip the guesswork.

Failed to pair: org.bluez.Error.NotReady

This error appears when the target device is not in discoverable mode, or when the local adapter is still initializing. Toggle the device's pairing button again and retry the pair command.

Failed to connect: org.bluez.Error.Failed

The daemon rejected the connection. This usually means the device is already connected to another computer, or the Bluetooth stack lost its state. Run remove 00:11:22:33:44:55 inside bluetoothctl, then start the pairing sequence from scratch.

Agent is already registered

You tried to run agent on twice. The daemon only allows one active agent per session. Run default-agent instead, or exit and restart bluetoothctl.

Hardware switches and laptop function keys can block the radio at the kernel level. Fedora respects the rfkill state. If the radio is soft-blocked, bluetoothctl will refuse to power on.

rfkill list
# Check for "Soft blocked: yes" or "Hard blocked: yes"
sudo rfkill unblock bluetooth
# Clear the software block if the hardware switch is off

When the daemon behaves strangely, check the journal before guessing. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu bluetooth muscle-memory style.

journalctl -xeu bluetooth
# Show recent daemon logs with explanatory context
# Look for "Failed to set scan parameters" or "Adapter not available"

Read the exact error string before restarting services. The daemon tells you exactly which layer failed.

When to use bluetoothctl versus other tools

Fedora ships with multiple ways to manage Bluetooth. Pick the tool that matches your workflow.

Use bluetoothctl when you need precise control over profiles, trust states, and agent behavior. Use the GNOME Bluetooth settings panel when you want a visual interface for quick pairing and volume control. Use blueman when you are running a desktop environment without native Bluetooth integration or need advanced network tethering features. Stick to the command line when you are managing headless servers or scripting device connections.

Match the tool to the task. GUIs hide state. The terminal shows it.

Where to go next