Stopping Bluetooth headphones from disconnecting on GNOME 48: a quick PipeWire tweak

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 by module-bluetooth-discover. keep_alive is a boolean; setting it to true forces 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:

MitigationCommand / SettingWhy it matters
Disable auto‑pairing for unknown devicesbluetoothctl → default-key-flagPrevents strangers from pairing without your consent.
Use rfkill to block the radio when not neededrfkill block bluetoothA quick way to turn the radio off during work or sleep.
Keep firmware up‑to‑datesudo fwupd refresh && sudo fwupd updateFixes 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

SymptomLikely causeFix
Headphones still disconnect after the tweakKernel power‑management is overriding PipeWireEdit /etc/bluetooth/main.conf and set IdleTimeout = 0
PipeWire fails to start after editing configSyntax error in 10-bluetooth.confRun pipewire --check to validate the config
Audio latency spikes after enabling keep_aliveThe headset’s firmware expects low‑power modeTry low_latency = true in the same config file
Battery drains noticeablyController stays on all the timeUse 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