Fix Bluetooth Not Working on Linux
Unblock the radio, make sure the BlueZ service is running, and power the adapter on:
rfkill unblock bluetooth
sudo systemctl enable --now bluetooth
bluetoothctl power on
bluetoothctl show
If bluetoothctl says No default controller available, the kernel didn't set up the adapter: check the firmware messages in Step 3.
Identify your problem
| Symptom | Likely cause | Section |
|---|---|---|
| No Bluetooth toggle in settings, "No adapter found" | Driver or firmware not loaded, or adapter disabled in firmware setup | Step 3 |
| Toggle exists but switches itself back off | rfkill block, airplane mode, or adapter crashing | Step 1 |
| Adapter works, device won't pair or connect | Stale pairing, wrong mode, dual-boot keys | Pairing fixes |
| Headphones connect, no sound or bad quality | Missing PipeWire Bluetooth plugin or HFP profile | Bluetooth audio |
| Works until suspend, then gone | USB autosuspend or driver not resuming | After suspend |
On Ubuntu specifically, the Ubuntu Bluetooth fix covers HWE kernels, the GNOME toggle and release-upgrade regressions.
Step 1: Check rfkill and airplane mode
rfkill list
Example output:
0: hci0: Bluetooth
Soft blocked: yes
Hard blocked: no
1: phy0: Wireless LAN
Soft blocked: no
Hard blocked: no
- Soft blocked: yes: software turned it off (airplane mode, the desktop toggle, or a saved state). Fix with
rfkill unblock bluetooth. - Hard blocked: yes: a physical switch, an Fn key combination or a firmware setting is blocking the radio. Software cannot override this; flip the switch, press the key (often Fn+F-key with an antenna icon) or enable Bluetooth/wireless in the BIOS/UEFI setup.
- No hci entry at all: the kernel has no Bluetooth adapter. Go to Step 3.
If the soft block comes back after every reboot, the systemd-rfkill service is restoring a saved "blocked" state. Unblock, then reboot once so the new state is saved.
Step 2: Check the BlueZ service
BlueZ is the Linux Bluetooth stack; bluetooth.service is its daemon.
systemctl status bluetooth
Example output:
● bluetooth.service - Bluetooth service
Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-10-15 09:12:04 CEST; 2h ago
If it says Unit bluetooth.service could not be found, BlueZ isn't installed (common on Arch and minimal installs):
| Distro | Install BlueZ |
|---|---|
| Ubuntu, Debian, Mint | sudo apt install bluez |
| Fedora | sudo dnf install bluez bluez-tools |
| Arch | sudo pacman -S bluez bluez-utils |
| openSUSE | sudo zypper install bluez |
Then sudo systemctl enable --now bluetooth. Arch does not enable it automatically. If the service is failed, journalctl -u bluetooth -b shows why. More on reading unit status is in systemd basics.
Make the adapter power on at boot
Some setups leave the adapter powered off after boot. In /etc/bluetooth/main.conf, under [Policy], set:
[Policy]
AutoEnable=true
Restart the service afterwards. Recent BlueZ versions default to this, but distro configs can override it.
Step 3: Adapter missing: driver and firmware
Find the adapter and what the kernel said about it:
lsusb | grep -i -E 'bluetooth|intel|realtek|mediatek|qualcomm|broadcom'
sudo dmesg | grep -i -E 'bluetooth|btusb|hci0|firmware'
Most internal adapters are USB devices, even on PCIe Wi-Fi combo cards, and use the btusb driver. Example output of a firmware failure:
Bluetooth: hci0: RTL: firmware file rtl_bt/rtl8852cu_fw.bin not found
Bluetooth: hci0: Direct firmware load for rtl_bt/rtl8852cu_fw.bin failed with error -2
The firmware file is missing. Install or update the firmware package and reboot:
| Distro | Firmware package(s) |
|---|---|
| Ubuntu, Mint | sudo apt install --reinstall linux-firmware |
| Debian 13 | sudo apt install firmware-realtek firmware-iwlwifi firmware-atheros firmware-brcm80211 (needs non-free-firmware) |
| Fedora | sudo dnf install linux-firmware (split into packages such as intel-*-firmware, realtek-firmware) |
| Arch | sudo pacman -S linux-firmware |
| openSUSE | sudo zypper install kernel-firmware-bluetooth |
Other messages and what they mean:
hci0: command 0x... tx timeoutorReading Intel version command failed: the adapter is stuck. Fully power off the laptop (not just reboot), unplug it for 30 seconds on desktops, then try again. On Intel combo cards this often clears it.Bluetooth: hci0: unexpected eventon a cheap USB dongle: many clone CSR dongles are partly broken. A recent kernel has workarounds; otherwise use another dongle.- No Bluetooth lines at all and nothing in
lsusb: the adapter is disabled in the BIOS/UEFI, or on a Wi-Fi combo card the Bluetooth part is wired through a USB header that isn't connected (some desktop add-in cards).
Brand-new adapters may need a newer kernel than your distro ships; on Ubuntu LTS the HWE kernel solves this.
Reload the driver
sudo modprobe -r btusb
sudo modprobe btusb
sudo systemctl restart bluetooth
This re-initialises the adapter without a reboot and fixes many "it just stopped" cases.
Pairing and connection fixes
Use bluetoothctl to see exactly where pairing fails; desktop dialogs often hide the error.
bluetoothctl
power on
agent on
default-agent
scan on
# wait for your device, e.g. Device AA:BB:CC:DD:EE:FF Headphones
pair AA:BB:CC:DD:EE:FF
trust AA:BB:CC:DD:EE:FF
connect AA:BB:CC:DD:EE:FF
scan off
quit
Remove and re-pair
Stale pairing data is the most common cause of Failed to connect: org.bluez.Error.Failed and AuthenticationFailed:
bluetoothctl remove AA:BB:CC:DD:EE:FF
Then put the device back in pairing mode (usually holding the power or Bluetooth button until the light flashes) and pair again. Many headphones also need to be "forgotten" on your phone, because they connect to the last-used host first.
Dual boot with Windows
Each pairing generates a new link key. Pair in Linux, boot Windows and pair there, and Linux's key is now invalid. Either re-pair every time you switch, or copy the Windows key into /var/lib/bluetooth/ADAPTER_MAC/DEVICE_MAC/info. The Arch Wiki dual boot pairing section walks through extracting the key.
Devices that need classic or LE mode
Some older devices fail when the adapter runs in dual mode. In /etc/bluetooth/main.conf, ControllerMode = bredr forces classic Bluetooth (for older headsets), le forces Low Energy only. Leave the default dual unless you have this specific problem.
Bluetooth audio (headphones, speakers)
Audio over Bluetooth goes through PipeWire, which needs its Bluetooth plugin:
| Distro | Package |
|---|---|
| Ubuntu, Debian, Mint | sudo apt install libspa-0.2-bluetooth |
| Fedora | Included in pipewire by default |
| Arch | sudo pacman -S pipewire-audio pipewire-pulse wireplumber |
| openSUSE | Included in the default PipeWire packages; sudo zypper install pipewire-pulseaudio if you replaced them |
Restart audio afterwards with systemctl --user restart wireplumber pipewire pipewire-pulse, then reconnect the headset.
Bad quality or mono sound
The headset is in HFP/HSP (hands-free) mode, which is low-quality but has a microphone. Switch to A2DP (high fidelity playback) in Settings → Sound, in pavucontrol → Configuration, or with wpctl:
wpctl status # note the ID of the Bluetooth device
wpctl set-profile ID 1 # the index of the a2dp-sink profile
Apps that open the microphone (video calls) switch the headset back to hands-free mode. That is a Bluetooth limitation for most headsets, not a Linux bug. For general audio troubleshooting see no sound on Linux.
Show headset battery level
GNOME and KDE show the battery level of many headsets and mice. For some devices BlueZ only reports it with experimental features enabled. In /etc/bluetooth/main.conf, under [General], set Experimental = true and restart bluetooth.service. Leave it off if you don't need it; experimental features can change between BlueZ releases.
Microphone on Bluetooth headsets
The headset's microphone only works in the hands-free profile (HFP). Modern headsets and current PipeWire versions support the mSBC codec there, which sounds noticeably better than classic CVSD. If your call audio is unusable, check that the headset is on HFP rather than the older HSP profile in pavucontrol → Configuration, and consider a separate USB microphone for long calls, so the headphones can stay in A2DP.
Bluetooth gone after suspend
Restart the stack first: sudo systemctl restart bluetooth, then reload btusb as shown above. If it happens every time, disable USB autosuspend for the Bluetooth driver:
echo 'options btusb enable_autosuspend=n' | sudo tee /etc/modprobe.d/btusb.conf
sudo reboot
You can test the same setting for one boot with the kernel parameter btusb.enable_autosuspend=n; see kernel boot parameters.
Last resort: reset Bluetooth completely
Deleting BlueZ's state forgets every paired device. You will need to pair everything again.
sudo systemctl stop bluetooth
sudo rm -rf /var/lib/bluetooth/*
sudo systemctl start bluetooth
If that doesn't help, test with a live USB of a newer release. If Bluetooth works there, a kernel or firmware update will fix your installed system; if it fails there too, suspect the hardware or a firmware setting. Collect sudo dmesg | grep -i bluetooth, bluetoothctl show and journalctl -u bluetooth -b before asking for help or filing a bug. The Arch Wiki Bluetooth page and BlueZ project are the upstream references; the systemctl cheat sheet covers the service commands.
Frequently asked questions
Why does bluetoothctl say No default controller available?
No Bluetooth adapter is registered with BlueZ. The adapter is blocked by rfkill, the kernel driver or firmware failed to load, or bluetooth.service is not running.
How do I restart Bluetooth on Linux?
Run sudo systemctl restart bluetooth. If the adapter itself is stuck, reload its driver with sudo modprobe -r btusb && sudo modprobe btusb.
Why do my Bluetooth headphones connect but play no sound?
The PipeWire Bluetooth plugin may be missing or the headset is in the hands-free (HFP) profile. Install the plugin for your distro and pick the A2DP high-fidelity profile in sound settings.
Why do I have to re-pair my device after booting Windows?
Each pairing creates a new link key, and dual-boot systems store a different key in each OS. Pair in Linux, then Windows, and copy the Windows key into Linux, or simply re-pair when you switch.
Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.