Why Bluetooth headphones keep dropping on GNOME 48
Bluetooth audio on GNOME 48 is now handled by PipeWire instead of the old PulseAudio stack. The new stack is cleaner, but it also turns on a “low‑power” mode that can make a headset drop after a few minutes of idle time or when you close the laptop lid. The real culprit is usually the kernel’s power‑management for the Bluetooth controller and PipeWire’s default settings.
The fix is a single, lightweight tweak that keeps the link alive without touching the kernel or the hardware. Below is a step‑by‑step guide, the reasoning behind it, and the most common pitfalls I’ve seen.
1. Quick sanity check
Before you touch any config files, make sure the headset itself isn’t the problem.
# Is the controller even showing up?
bluetoothctl list
# Look for disconnect messages in the kernel logs
journalctl -b -u bluetooth.service | grep -i disconnect
If you see “Connection terminated” or “Device lost” in the logs, the stack is probably at fault. If the logs are quiet, the issue might be in the audio routing or the headset’s own power‑saving mode.
2. What PipeWire does by default
When you pair a Bluetooth audio device, PipeWire loads module‑bluetooth-discover. In GNOME 48 the module comes with these defaults:
auto_enable = true– enable the device as soon as it’s paired.low_latency = false– use the normal audio path.keep_alive = false– allow the kernel to power‑down the controller after a period of inactivity.
It’s the keep_alive flag that usually triggers the drop. When the controller powers down, the headset’s link is lost and you have to re‑pair to get audio back.
3. The PipeWire tweak
Just enable keep_alive for Bluetooth devices. That tells PipeWire to keep the controller powered on as long as any audio stream is active, even if the headset itself is idle.
3.1. Create a user‑level configuration file
PipeWire reads snippets from /etc/pipewire/pipewire.conf.d/ and ~/.config/pipewire/pipewire.conf.d/. A user‑level file is the safest place—no root needed and it survives upgrades.
mkdir -p ~/.config/pipewire/pipewire.conf.d
cat > ~/.config/pipewire/pipewire.conf.d/10-bluetooth.conf <<'EOF'
# Keep the Bluetooth controller alive while audio is in use
[bluetooth]
keep_alive = true
EOF
Tip: The
[bluetooth]section is read bymodule-bluetooth-discover.keep_aliveis a boolean; setting it totrueforces the kernel to keep the controller powered.
3.2. Reload PipeWire
PipeWire watches its config directories, but a manual reload guarantees the change takes effect right away.
systemctl --user restart pipewire
systemctl --user restart pipewire-pulse
If you’re using the pipewire-pulse compatibility layer (the default in GNOME 48), restarting it is essential; otherwise the audio routing will still use the old settings.
3.3. Verify the change
# List active modules
pactl list modules | grep -i bluetooth
# Inspect the module parameters
pactl list modules | grep -i keep_alive
You should see keep_alive = true in the output. If it’s still false, double‑check the file path and syntax—PipeWire is picky about section names and key formatting.
4. Why this works
With keep_alive enabled, PipeWire sends a “keep‑alive” request to the kernel every few seconds while any audio stream is active. The kernel interprets this as a “busy” flag and keeps the controller powered. It’s the same mechanism that older bluetoothd used when the IdleTimeout option was disabled.
The trade‑off is a tiny increase in battery drain because the controller stays awake. For most users the extra drain is negligible compared to the benefit of uninterrupted audio.
5. Security considerations
Keeping the Bluetooth radio on all the time can expose the machine to passive eavesdropping or unauthorized pairing attempts. Mitigate the risk with these practices:
| Mitigation | Command / Setting | Why it matters |
|---|---|---|
| Disable auto‑pairing for unknown devices | bluetoothctl → default-key-flag | Prevents strangers from pairing without your consent. |
Use rfkill to block the radio when not needed | rfkill block bluetooth | A quick way to turn the radio off during work or sleep. |
| Keep firmware up‑to‑date | sudo fwupd refresh && sudo fwupd update | Fixes known Bluetooth vulnerabilities. |
The tweak itself only affects power state; it doesn’t change the encryption level of the audio stream. PipeWire uses the same security mechanisms as BlueZ, so no extra steps are needed unless you want stricter pairing policies.
6. Common pitfalls and how to fix them
| Symptom | Likely cause | Fix |
|---|---|---|
| Headphones still disconnect after the tweak | Kernel power‑management is overriding PipeWire | Edit /etc/bluetooth/main.conf and set IdleTimeout = 0 |
| PipeWire fails to start after editing config | Syntax error in 10-bluetooth.conf | Run pipewire --check to validate the config |
Audio latency spikes after enabling keep_alive | The headset’s firmware expects low‑power mode | Try low_latency = true in the same config file |
| Battery drains noticeably | Controller stays on all the time | Use rfkill block bluetooth when idle or set IdleTimeout back to a non‑zero value |
6.1. Kernel power‑management override
Some distributions enable IdleTimeout in /etc/bluetooth/main.conf. If you still see disconnections even after enabling keep_alive, edit the file:
sudo nano /etc/bluetooth/main.conf
Add or modify:
[Policy]
IdleTimeout = 0
A value of 0 disables the timeout entirely. Restart the Bluetooth daemon afterward:
sudo systemctl restart bluetooth.service
6.2. Validating PipeWire configuration
PipeWire ships with a built‑in validator. Run it to catch syntax errors:
pipewire --check
If the validator reports errors, the output will point to the offending line. Fix the typo, then reload PipeWire again.
6.3. Low‑latency mode
If you notice a 30 ms latency spike after the tweak, add:
[bluetooth]
keep_alive = true
low_latency = true
low_latency forces PipeWire to use the “high‑performance” audio path, which can help if the headset’s firmware behaves better in that mode.
7. Bottom line
Enabling keep_alive in PipeWire’s Bluetooth module is a quick, safe way to stop your headphones from dropping on GNOME 48. It keeps the kernel from power‑down the controller while you’re listening, without touching the kernel or hardware. Just remember to keep an eye on battery life and stay vigilant about pairing security.
Enjoy the uninterrupted music!
TAGS: linux, bluetooth, pipewire, gnome, audio
See also
- When a systemd timer for a backup job stops after a kernel update: the `Persistent=true` fix
- Using systemd‑cgtop to Spot the Service Eating All Your Memory
- Pinning the NVIDIA Driver on Ubuntu 24.04 to Avoid Kernel Update Breakage
- How a Forgotten Search Domain in /etc/resolv.conf Broke Docker Container DNS and How I Restored It
- Quickly Restore a Single File From a Borg Backup on an NFS Share