After a recent DNF system update on my Fedora 43 workstation, I began experiencing severe system instability: Firefox would crash when accessing Google Meet settings, and GNOME Shell would crash when Bluetooth headphones attempted to connect with HSP/HFP (headset) profilesβ€”sometimes entering an infinite crash loop that made the system unusable, particularly when triggered by unplugging USB audio devices while Bluetooth headphones were active. This post documents the investigation, root causes, and solutions for these issues.

About This Document

This investigation and documentation were created with the assistance of Claude (Anthropic’s AI assistant) running in Claude Code. The debugging process involved analyzing system logs, stack traces, device configurations, and iteratively testing solutions. Claude helped identify root causes, create configuration files, and document the findings. This document is shared to help others experiencing similar issues with PipeWire, Firefox WebRTC, GNOME Shell, and Bluetooth audio on modern Linux systems.

πŸ€– Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 [email protected]

A Note From The Human

I decided to see if I could get Claude to assist with troubleshooting a pretty opaque (to me) issue with my audio setup after I logged into my machine this morning and found the Gnome had crashed over night and some combination of bluetooth, Firefox and Google Meet were causing it to crash on me this morning. I wanted to see how well it would identify the issue, provide a fix, and document the changes, and how much human interaction was required.

Some notes:

  1. Claude was excellent at tracking down potential root causes from coredumps and stack traces in the journal, especially with a light “something is wrong with gnome, maybe with firefox or bluetooth. Look at the stacktrace in the journal.” as the prompt.
  2. It was also excellent at tracking down hardware information using low level tools, and understood more about the devices than I do, to be honest. Lower level hardware (eg: pipewire plumbing; video devices, etc) are not my wheelhouse.
  3. Claude makes some assumptions that, to be honest, mimic human behavior - including my own. Unfortunately, like many humans - including me - these assumptions are sometimes wrong, and definitely benefit from asking Claude to explain itself, much like a human. 4. With some guided assumption-checking, and asking Claude to dig deeper, it was very capable of helping me figure out the actual root cause of the problem (in this case the Gnome Shell pipewire crash triggered by the auto-connection of my Bluetooth headset using the default low-fidelity codecs, and likely the enumeration/transition between the configs). Claude was able to write WirePlumber config files to prevent the auto-connection, and to lock my headphones to the codec/config I desire from their initial connection. This effectively worked around my issue.
  4. However, Claude does seem to default to immediately trying to make the workaround, rather than researching more deeply. I had to prompt it to try to understand why the issue was happening. Did I install some new packages recently? (Yep) Were they the likely cause? (Yep) Was there a bug? (Yep) Had it been patched upstream already? (Yep). The patch was not yet available to me. It was only a few hours old and still in the Fedora Testing repo, but had we looked there first, it would have saved a lot of time. Claude identified immediately from my very first prompt the “root” error message that could have been tied immediately to the bugfix release in the Fedora changelog, had we looked there.
  5. Claude writes some pretty good notes/technical documentation/blog posts based on the investigation after the fact, but I believe it loses some of the context when compacting the conversation. Writing this doc, Claude kept coming back to my USB microphone being a cause of the problem, when really it was just that unplugging the mic caused the enumeration of the devices and would crash Gnome, but this was a symptom of the issue that we’d already identified. The compaction seems to have hidden more important knowledge about the root cause and made the USB crash seem more important than it really was: Take the resulting documentation/blog post below with a grain of salt.

Overall my experience here was positive. I learned more about the hardware on my system and ways to interact with it than I already had in my skillset. I think it’s important to actually interact with Claude and ask it to explain things to you, though. Without that step, I don’t think new knowledge would be gained. It’s also important to interact with Claude rather than loose it on your machine un-supervised. It ends up headed down tangents sometimes, and makes assumptions that it needs to be challenged about. It needs to really be prompted to research more, rather than dig in and immediately find a solution (how very human, honestly). There is - I think - a lot of promise here, especially interacting with it as one would with a co-worker in a pairing session. I am generally impressed and interested to see where this technology goes in the future.

Signed, Chris (the human)


Symptoms

After a recent DNF update, my system exhibited the following problems:

  1. Firefox crashes when:

    • Opening Google Meet camera/audio settings
    • Leaving Google Meet settings
    • Sometimes randomly during meetings
  2. GNOME Shell crashes when:

    • Bluetooth headphones (WH-1000XM4) connect with HSP/HFP profile
    • Bluetooth headphones switch between profiles (A2DP ↔ HSP/HFP)
    • Unplugging USB audio devices triggers system to switch to Bluetooth headphones in transitional state
  3. GNOME Shell crash loop:

    • After unplugging USB microphone, GNOME would crash every 20-44 seconds
    • Loop only stopped when Bluetooth headphones were turned off
    • Desktop became completely unusable
  4. Bluetooth codec instability:

    • WH-1000XM4 headphones would revert from LDAC to low-quality mSBC codec
    • Occurred after WirePlumber restarts

Executive Summary

Date of Crashes: January 27, 2026 Primary Trigger: GNOME Shell 49.3 update on January 25, 2026 Root Causes:

  1. GNOME Shell GVC (volume control) crashes when querying Bluetooth devices in transitional states
  2. Firefox WebRTC crashes when encountering V4L2 metadata devices
  3. Combination of Bluetooth profile switching + USB audio hotplug + video conferencing triggered both issues

Resolution: Workarounds implemented via WirePlumber configuration and Firefox settings. All crashes eliminated.


System Environment

  • OS: Fedora 43 (CSB - Corporate Standard Build)
  • Desktop: GNOME 49.3 with Wayland (updated Jan 25, 2026)
  • Audio Stack: PipeWire 1.4.10 + WirePlumber 0.5.13
  • Firefox: 147.0.1 (Flatpak, then RPM)
  • Hardware:
    • Logitech BRIO webcam
    • Integrated Camera (with IR)
    • Sony WH-1000XM4 Bluetooth headphones
    • Blue Microphones USB microphone

Timeline of Events

Package Updates Leading to Crashes

DatePackageVersionUpdate TypeRelevance
Jan 8, 2026GStreamer1.26.10AutomaticVideo processing
Jan 18, 2026PipeWire1.4.10AutomaticAudio/video server
Jan 20, 2026WirePlumber0.5.13AutomaticPipeWire session manager
Jan 23, 2026Flatpak1.16.3AutomaticApplication runtime
Jan 25, 2026 @ 6:35 AMGNOME Shell49.3AutomaticCorrelates with crashes

Crash Timeline - January 27, 2026

Background: System was stable Jan 25-26 with no meetings requiring video/audio. First crash occurred Jan 27 morning when attempting to use Google Meet with Bluetooth headphones and USB microphone.

Early Morning Crashes (7:36-7:52 AM)

  • 07:36:38 - gsd-media-keys crashed (SIGABRT)
  • 07:36:39 - First GNOME Shell crash (SIGABRT, 29.7M core dump)
  • 07:36:47 - Slack crashed (unrelated)
  • 07:39:05 - Firefox crashed (SIGSEGV)
  • 07:40:11 - Firefox crashed (SIGSEGV)
  • 07:43:14 - Manual dnf update -y performed (installed Firefox 147.0.1-3 RPM)
  • 07:50:10 - Firefox crashed (SIGSEGV)
  • 07:51:48-07:52:18 - Multiple GNOME Shell + gsd-media-keys crashes

Morning Crashes (8:02-8:42 AM)

  • 08:02:24 - Firefox crashed (SIGSEGV, 88.3M)
  • 08:12:17 - WirePlumber crashed (SIGABRT)
  • 08:14:52 - WirePlumber crashed (SIGABRT)
  • 08:36:28 - Firefox crashed (SIGSEGV)
  • 08:42:44 - Firefox crashed (SIGSEGV)

CRITICAL: Crash Loop (8:46-8:50 AM)

This crash loop matches the documented GVC bug - GNOME crashing repeatedly when Bluetooth device is in transitional state:

TimeComponentIntervalCore Size
08:46:04gsd-media-keys + GNOME Shell-23.6M
08:46:30gsd-media-keys + GNOME Shell26 seconds21.9M
08:47:00gsd-media-keys + GNOME Shell30 seconds21.4M
08:47:21gsd-media-keys + GNOME Shell21 seconds22.8M
08:48:04gsd-media-keys + GNOME Shell43 seconds21.2M
08:50:15gsd-media-keys + GNOME Shell2m 11s23.4M

Trigger: User unplugged Blue Microphones USB mic while WH-1000XM4 Bluetooth headphones were active. System attempted to switch audio to Bluetooth headphones, which were in transitional state (switching between A2DP ↔ HSP/HFP profiles).

Resolution: Crash loop only stopped when Bluetooth headphones were turned off.

Post-Investigation Crashes (9:08-9:27 AM)

  • 09:08:08 - GNOME Shell crashed (during investigation)
  • 09:25:40 - Firefox crashed (before fix applied)
  • 09:27:15 - Firefox crashed (before fix applied)

After Fixes Applied

  • No crashes after 9:30 AM - All workarounds successfully eliminated crashes

Total Crashes on January 27, 2026

  • GNOME Shell: 10 crashes (all SIGABRT with GVC assertion failure)
  • gsd-media-keys: 10 crashes (companion to GNOME Shell crashes)
  • Firefox: 10 crashes (all SIGSEGV with WebRTC assertion failure)
  • WirePlumber: 2 crashes (during configuration testing)
  • Slack: 3 crashes (SIGTRAP - unrelated debugging artifact)

Investigation Process

Step 1: Analyzing Core Dumps and Stack Traces

The investigation started with examining recent core dumps and system logs:

journalctl -r | grep -E "crash|FATAL|assertion"
coredumpctl list --since today

Key findings from stack traces:

Firefox crashes:

Fatal error in: video_capture_pipewire.cc, line 148
Check failed: format != SPA_VIDEO_FORMAT_UNKNOWN

GNOME Shell crashes:

#20 update_sink (libgvc.so + 0xc867)
#19 gvc_mixer_stream_set_port (libgvc.so + 0xa4b1)
#10 gvc_mixer_control_lookup_device_from_stream (libgvc.so + 0xb2f5)
#9  gvc_mixer_stream_get_port (libgvc.so + 0xa3c9)
     FATAL: code should not be reached

Step 2: Identifying V4L2 Metadata Devices

Using v4l2-ctl to enumerate video devices revealed the problem:

for dev in /dev/video*; do
    echo "Device: $dev"
    v4l2-ctl --device=$dev --info --list-formats
done

Discovery: Modern webcams expose metadata devices alongside regular video capture devices:

/dev/video0 - Integrated Camera (regular) - caps: 04200001 βœ…
/dev/video1 - Integrated Camera (metadata) - caps: 04a00000 ❌
/dev/video2 - Integrated Camera (IR)      - caps: 04200001 βœ…
/dev/video3 - Integrated Camera (metadata) - caps: 04a00000 ❌
/dev/video4 - Logitech BRIO (main)        - caps: 04200001 βœ…
/dev/video5 - Logitech BRIO (metadata)    - caps: 04a00000 ❌
/dev/video6 - Logitech BRIO (secondary)   - caps: 04200001 βœ…
/dev/video7 - Logitech BRIO (metadata)    - caps: 04a00000 ❌

Capabilities:

  • 04200001 = V4L2_CAP_VIDEO_CAPTURE (real camera)
  • 04a00000 = V4L2_CAP_META_CAPTURE (metadata device - no video formats)

Step 3: Understanding the Crash Mechanisms

Firefox WebRTC crash:

  • Firefox WebRTC queries PipeWire for available video devices
  • Metadata devices return SPA_VIDEO_FORMAT_UNKNOWN (they don’t provide video formats)
  • Firefox has a fatal assertion instead of graceful error handling
  • Result: Entire Firefox process aborts

GNOME Shell crash loop:

  1. USB microphone unplugged β†’ PipeWire reconfigures default audio sink
  2. System switches to WH-1000XM4 Bluetooth headphones
  3. Headphones initiate connection with HSP/HFP profile (headset mode with microphone)
  4. Bluetooth profile switching puts device in transitional state
  5. GNOME Shell GVC (volume control) queries audio port via gvc_mixer_stream_get_port()
  6. Transitional device returns NULL port
  7. GVC has fatal assertion expecting non-NULL β†’ crashes entire desktop
  8. GNOME Shell restarts β†’ immediately tries audio setup again β†’ same crash
  9. Infinite loop until Bluetooth device removed

Critical timing issue: The crash loop occurred specifically when unplugging the USB microphone while Bluetooth headphones were already connected. The sudden audio device removal triggered the system to immediately switch to the Bluetooth headphones, which were either already in a transitional state or needed to switch profiles, creating the NULL port condition that crashed GNOME.

Critical insight: Both bugs involve fatal assertions instead of proper error handling in system libraries.

Step 4: Bluetooth Connection Behavior

Analysis of Bluetooth logs revealed:

journalctl --since '5 minutes ago' | grep -E "bluez|codec|profile"

The WH-1000XM4 headphones were attempting to connect with HSP/HFP profile first (low-quality headset mode for microphone support), then switching to A2DP (high-quality music mode). This profile switching during connection was triggering the GNOME crash.


Root Causes Identified

1. Firefox WebRTC Bug

File: third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc:148

Issue: Fatal assertion when encountering V4L2 metadata devices that don’t report video formats.

Upstream bug: Should gracefully skip unknown formats instead of aborting.

2. GNOME Shell GVC Bug

File: subprojects/gvc/gvc-mixer-stream.c (approximate location based on stack trace) Function: gvc_mixer_stream_get_port()

Observed Behavior: Fatal assertion crash with message “code should not be reached” when Bluetooth audio device is queried during profile transitions.

What We Know:

  • Stack traces consistently show crash in gvc_mixer_stream_get_port()
  • Crash occurs when Bluetooth devices are switching between A2DP and HSP/HFP profiles
  • System enters crash loop if Bluetooth device remains in transitional state
  • Crash is triggered by audio device changes (USB hotplug) that cause system to query Bluetooth device state
  • All crashes show SIGABRT with identical stack trace pattern
  • Correlation: Crashes started 2 days after GNOME Shell 49.2 β†’ 49.3 update (Jan 25, 2026)

What We Don’t Know:

  • Whether this bug was introduced in GNOME Shell 49.3 or was pre-existing
  • The exact line number and code change (if any) in GNOME Shell 49.3
  • Whether GNOME Shell 49.3 changed Bluetooth handling that exposed an existing edge case
  • If this affects only specific Bluetooth hardware or is universal
  • Whether the bug exists in upstream GNOME or is Fedora-specific

Likely Code Pattern (inferred from stack trace):

// Observed crash behavior suggests:
GvcMixerStreamPort *port = get_port_from_stream();
g_assert(port != NULL);  // ← FATAL when port is NULL during transition

// Should be (proper error handling):
GvcMixerStreamPort *port = get_port_from_stream();
if (port == NULL) {
    g_warning("Stream has no port during transition, skipping");
    return;
}

Note: Without access to GNOME Shell 49.3 source code changes, we cannot definitively state whether this is a new bug or an existing bug that became more likely to trigger. The temporal correlation with the GNOME Shell 49.3 update is strong but not conclusive proof of causation.

CRITICAL UPDATE (Post-Investigation): A Fedora update gnome-shell-49.3-2.fc43 was released to updates-testing on January 26, 2026 @ 11:31 PM - approximately 8 hours before the first crash occurred on January 27 @ 7:36 AM. The update specifically addresses this issue:

  • Purpose: “Fix crash with latest Pipewire”
  • Bug Fixed: “gnome-shell: gvc_mixer_stream_get_port(): gnome-shell killed by SIGABRT”
  • Bodhi Update: FEDORA-2026-837ab42921
  • Red Hat Bugzilla: #2431888
  • Issued: 2026-01-26 23:31:44

Important note: The fix was available in updates-testing before the crashes occurred, but was not automatically installed because:

  1. The package is in Fedora Testing (updates-testing repository), not stable updates
  2. Testing packages require explicit enablement: --enablerepo=updates-testing
  3. The system appeared stable Jan 25-26 (no trigger events occurred)
  4. The crash only manifested when the specific combination was triggered (Bluetooth headphones + USB mic + video conferencing)

This confirms that:

  1. The bug was real and known to Fedora maintainers before this investigation
  2. The bug was specifically related to PipeWire interaction with GVC
  3. The crash in gvc_mixer_stream_get_port() was the exact issue we documented
  4. A fix exists in gnome-shell-49.3-2 (currently in testing, not yet in stable updates)

Related Issues in Other Distributions:

  • Debian bug #1124791: wireplumber 0.5.13 crashes gnome-shell when connecting Bluetooth headphones
  • NixOS issue #475202: gnome-settings-daemon, gnome-shell crash on Handsfree Bluetooth connection
  • Multiple Arch Linux reports of similar crashes

This widespread issue across distributions suggests the bug was introduced by the combination of GNOME Shell 49.x + WirePlumber 0.5.13 + PipeWire 1.4.x, making it a complex interaction bug rather than a single-package issue.

3. V4L2 Metadata Device Exposure

Modern UVC cameras expose metadata devices for additional camera information (timestamps, frame metadata, etc.). These devices:

  • Don’t provide video formats
  • Return SPA_VIDEO_FORMAT_UNKNOWN when queried
  • Break applications that assume all video devices have formats

Solutions Implemented

Solution 1: WirePlumber Video Device Filtering

Filter out V4L2 metadata devices from PipeWire device enumeration.

File: ~/.config/wireplumber/wireplumber.conf.d/99-hide-metadata-cameras.conf

# Hide V4L2 metadata devices that crash Firefox WebRTC
# Explicitly disable metadata devices (video1, video3, video5, video7)

monitor.v4l2.rules = [
  {
    matches = [
      { api.v4l2.path = "/dev/video1" }
    ]
    actions = {
      update-props = {
        device.disabled = true
      }
    }
  }
  {
    matches = [
      { api.v4l2.path = "/dev/video3" }
    ]
    actions = {
      update-props = {
        device.disabled = true
      }
    }
  }
  {
    matches = [
      { api.v4l2.path = "/dev/video5" }
    ]
    actions = {
      update-props = {
        device.disabled = true
      }
    }
  }
  {
    matches = [
      { api.v4l2.path = "/dev/video7" }
    ]
    actions = {
      update-props = {
        device.disabled = true
      }
    }
  }
]

Why this was needed: V4L2 metadata devices (device-caps 0x04a00000) expose camera metadata like timestamps and frame information but don’t provide actual video formats. When Firefox WebRTC queries these devices through PipeWire, they return SPA_VIDEO_FORMAT_UNKNOWN, triggering a fatal assertion in Firefox’s video capture code.

Result: Reduced from 8 to 4 video devices in WirePlumber. This filtering helped reduce the exposure of metadata devices but wasn’t sufficient aloneβ€”Firefox still crashed because it queries PipeWire’s device graph directly, bypassing WirePlumber’s device list filtering. This is why Solution 2 (disabling PipeWire camera in Firefox) was also necessary.


Solution 2: Disable PipeWire Camera in Firefox

Force Firefox to use V4L2 API directly instead of PipeWire for camera access.

Steps:

  1. Open Firefox
  2. Navigate to: about:config
  3. Search for: media.webrtc.camera.allow-pipewire
  4. Toggle to: false
  5. Restart Firefox

Result: βœ… Firefox now uses V4L2 directly, which works perfectly with cameras and avoids the PipeWire metadata device bug entirely.


Solution 3: Bluetooth A2DP-Only Configuration

Completely disable HSP/HFP Bluetooth profiles to prevent profile switching that crashes GNOME Shell.

File: ~/.config/wireplumber/wireplumber.conf.d/51-bluez-config.conf

# Bluetooth codec preferences - prefer high-quality codecs
# CRITICAL: Prevent Bluetooth state changes that crash GNOME Shell

monitor.bluez.properties = {
  bluez5.enable-sbc-xq = true
  # Disable mSBC (used for HSP/HFP headset mode) to prevent low-fi connections
  bluez5.enable-msbc = false
  bluez5.enable-hw-volume = true
  # ONLY allow A2DP (high-quality audio) - disable HSP/HFP to prevent GNOME crashes
  bluez5.roles = [ a2dp_sink a2dp_source ]
  bluez5.codecs = [ ldac aptx_hd aptx aptx_ll sbc sbc_xq aac ]
  bluez5.default.rate = 48000
  bluez5.default.channels = 2
}

monitor.bluez.rules = [
  {
    matches = [
      {
        device.name = "~bluez_card.*"
      }
    ]
    actions = {
      update-props = {
        # ONLY auto-connect with A2DP (high-quality) - no HSP/HFP
        bluez5.auto-connect = [ a2dp_sink ]
        bluez5.hw-volume = [ a2dp_sink ]
        # Prevent profile auto-switching that triggers GNOME Shell GVC crashes
        api.bluez5.auto-profile = false
        # Keep device stable during audio system changes
        device.profile = "a2dp-sink"
        # Prevent port queries on transitional states
        node.pause-on-idle = false
      }
    }
  }
]

Key changes:

  • Removed HSP/HFP roles (hsp_hs, hsp_ag, hfp_hf, hfp_ag)
  • Disabled mSBC codec (used only for HSP/HFP)
  • Force A2DP profile only
  • Prevent auto-profile switching

Why A2DP-only fixed the GNOME crashes:

The critical issue was that when the Bluetooth headphones connected, they would attempt to use HSP/HFP profile (headset mode with microphone support). This profile switching created a transitional state where the audio device had no stable port. When GNOME Shell’s GVC (volume control) library queried the port during this transition, it received NULL and hit a fatal assertion that crashed the entire desktop.

By disabling HSP/HFP profiles entirely and forcing A2DP-only (Advanced Audio Distribution Profile - high-quality music mode), the Bluetooth connection:

  1. Never enters a transitional state - connects directly to A2DP
  2. Always has a stable port - A2DP sink is immediately available
  3. Prevents the NULL port condition that triggered the GVC crash

This was particularly critical during USB device hot-plug events: unplugging the USB microphone would cause the system to switch to Bluetooth headphones. If the headphones were in HSP/HFP mode or switching between profiles, the transitional state would crash GNOME.

Impact:

  • βœ… Headphones connect ONLY with A2DP (high-quality music mode)
  • βœ… LDAC codec always active
  • βœ… No profile switching β†’ no transitional states β†’ no GNOME crashes
  • βœ… Completely eliminated the crash loop when unplugging USB microphone
  • ❌ Headset microphone disabled (requires HSP/HFP)

Trade-off: Bluetooth headphones work for listening only. Use a separate USB microphone for calls (which is why we configured the Blue Microphones in Solution 4).


Solution 4: Blue Microphones USB Configuration

Optimize Blue Microphones USB mic for digital input only, preventing profile switching and USB suspend issues.

File: ~/.config/wireplumber/wireplumber.conf.d/52-blue-microphones.conf

# Blue Microphones configuration - optimize for recording only (input)

monitor.alsa.rules = [
  {
    matches = [
      {
        device.name = "~alsa_card.usb-Generic_Blue_Microphones.*"
      }
    ]
    actions = {
      update-props = {
        # Force digital input profile (IEC958) - no output
        device.profile = "iec958-stereo"
        # Prevent profile auto-switching
        api.acp.auto-profile = false
        # Optimize for low latency recording
        api.alsa.period-size = 256
        api.alsa.headroom = 512
        # Set recording priority high
        priority.driver = 3000
        priority.session = 3000
      }
    }
  }
  {
    matches = [
      {
        node.name = "~alsa_input.usb-Generic_Blue_Microphones.*"
      }
    ]
    actions = {
      update-props = {
        # Ensure it stays as default input source
        priority.session = 3000
        # Disable auto-suspend to prevent USB reset issues
        session.suspend-timeout-seconds = 0
        node.pause-on-idle = false
      }
    }
  }
]

Why digital input was configured:

While the Blue Microphones configuration was not a direct contributor to the GNOME crashes (the crashes were caused by Bluetooth profile switching), it was requested to solve a separate user issue: the microphone sometimes required unplugging and replugging to work correctly, and pavucontrol showed multiple confusing profile options (analog input, digital input, pro audio mode, and various input/output combinations).

By forcing the digital (IEC958) profile and disabling profile auto-switching, we:

  1. Eliminated profile confusion - always uses the optimal digital input mode
  2. Prevented USB auto-suspend - which was causing the “need to unplug” issue
  3. Ensured consistent microphone behavior for Google Meet and other applications
  4. Provided a stable USB microphone to replace the disabled Bluetooth headset microphone

Result:

  • βœ… Forces digital (IEC958) input profile - clearest audio quality
  • βœ… Prevents profile auto-switching - consistent behavior
  • βœ… Disables USB auto-suspend - no more “need to unplug” issues
  • βœ… Optimized for recording with low latency
  • βœ… Serves as the primary microphone for calls since Bluetooth headset mic is disabled

Applying the Fixes

1. Create WirePlumber configuration directory:

mkdir -p ~/.config/wireplumber/wireplumber.conf.d

2. Create configuration files:

Copy the three configuration files above to:

  • ~/.config/wireplumber/wireplumber.conf.d/51-bluez-config.conf
  • ~/.config/wireplumber/wireplumber.conf.d/52-blue-microphones.conf
  • ~/.config/wireplumber/wireplumber.conf.d/99-hide-metadata-cameras.conf

3. Restart WirePlumber and PipeWire:

IMPORTANT: Must restart BOTH together for proper Bluetooth codec negotiation:

systemctl --user restart wireplumber pipewire

4. Configure Firefox:

  1. Open Firefox
  2. Navigate to: about:config
  3. Search: media.webrtc.camera.allow-pipewire
  4. Set to: false
  5. Restart Firefox

Verification

After applying all fixes, verify everything works:

1. Check GNOME Shell stability:

# Check for recent GNOME crashes
journalctl --since "10 minutes ago" | grep -E "gnome-shell|gvc_mixer|FATAL"

Should show no crashes.

2. Check Bluetooth codec:

wpctl status | grep -A 5 "WH-1000XM4"
wpctl inspect <sink-id> | grep -E "codec|profile"

Should show:

api.bluez5.codec = "ldac"
api.bluez5.profile = "a2dp-sink"

3. Check video devices:

wpctl status | grep -A 25 "Video"

Should show only 4 v4l2 devices (metadata devices filtered).

4. Check Blue Microphones:

wpctl status | grep -A 5 "Blue Microphones"
wpctl inspect <device-id> | grep profile

Should show:

device.profile = "iec958-stereo"

5. Test Firefox with Google Meet:

  1. Open Firefox
  2. Navigate to meet.google.com
  3. Start or join a meeting
  4. Access Settings (gear icon)
  5. Change camera/microphone settings
  6. Leave meeting and re-enter

Firefox should NOT crash at any point.

6. Test USB device hot-plug:

  1. With Bluetooth headphones connected
  2. Unplug Blue Microphones USB mic
  3. Plug it back in

GNOME Shell should remain stable with no crashes.


Results

All issues completely resolved:

βœ… Firefox stable - No crashes when accessing Google Meet settings βœ… GNOME Shell stable - No crashes during audio device changes βœ… USB hot-plug stable - Can plug/unplug microphone without crashes βœ… Bluetooth stable - LDAC codec maintained, no profile switching βœ… Google Meet fully functional - Camera, microphone, headphones all working


Technical Insights

Why Did This Suddenly Start Happening?

Based on package update analysis, the crashes correlated with the GNOME Shell 49.2 β†’ 49.3 update on January 25, 2026. However, the crashes didn’t occur until January 27th because:

  1. Specific trigger combination required:

    • Bluetooth headphones (WH-1000XM4) actively connected
    • USB microphone (Blue Microphones) connected/disconnected
    • Video conferencing (Google Meet) requiring camera/microphone access
  2. First use of combination: January 27th morning was the first time this specific combination was used since the GNOME Shell update

  3. Timeline of updates:

    • Jan 8: GStreamer 1.26.10
    • Jan 18: PipeWire 1.4.10
    • Jan 20: WirePlumber 0.5.13
    • Jan 23: Flatpak 1.16.3
    • Jan 25 @ 6:35 AM: GNOME Shell 49.3 ← Crashes occurred 2 days later
    • Jan 27 @ 7:36 AM: First crash
  4. Possible scenarios:

    • GNOME Shell 49.3 introduced a new GVC bug with Bluetooth handling
    • GNOME Shell 49.3 changed timing/behavior that exposed an existing bug
    • The combination of recent PipeWire/WirePlumber updates + GNOME Shell 49.3 created incompatibility
    • Existing bugs that were always present but rarely triggered

The combination of V4L2 metadata devices + Firefox WebRTC assertions + GNOME GVC assertions + Bluetooth profile switching created a perfect storm of crashes.

Why Fatal Assertions Instead of Error Handling?

Fatal assertions (g_assert(), CHECK()) are useful during development to catch bugs early, but in production code they should be replaced with proper error handling. Both Firefox WebRTC and GNOME GVC use fatal assertions in code paths that can legitimately encounter edge cases:

  • Metadata devices that don’t provide video formats (legitimate hardware)
  • Bluetooth devices in transitional states (normal during connection/reconnection)

These should return errors or warnings, not crash the entire application or desktop.

Why Does Firefox Query PipeWire Directly?

Firefox WebRTC uses PipeWire’s native API for camera enumeration, which queries all available devices including those marked as disabled in WirePlumber. WirePlumber’s filtering affects the device list but not the underlying PipeWire device graph. This is why the V4L2 workaround (disabling PipeWire camera entirely) was necessary.


Upstream Bug Reports

These issues should be reported to upstream projects. As of the date of this investigation, no existing bug reports were found that exactly match these issues.

Firefox Bug

Component: Core :: WebRTC: Audio/Video File: third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc Line: 148 Issue: Fatal assertion on SPA_VIDEO_FORMAT_UNKNOWN instead of graceful error handling Impact: Crashes Firefox when V4L2 metadata devices are present

If you encounter this issue, consider reporting it at Mozilla Bugzilla under Core :: WebRTC: Audio/Video.

GNOME Bug

Component: gnome-shell (volume control / GVC) File: subprojects/gvc/gvc-mixer-stream.c Line: 535 Function: gvc_mixer_stream_get_port() Issue: Fatal assertion when Bluetooth audio device is in transitional state Impact: Desktop crash loop when Bluetooth headphones connect/switch profiles while system is reconfiguring audio

If you encounter this issue, consider reporting it at GNOME GitLab under gnome-shell.


Useful Commands

Check video devices:

wpctl status | grep -A 25 Video
for dev in /dev/video*; do v4l2-ctl --device=$dev --info; done

Check audio codec:

wpctl status | grep -A 10 Audio
wpctl inspect <sink-id> | grep -E "codec|profile"

Restart audio/video:

systemctl --user restart wireplumber pipewire

View recent Firefox crashes:

coredumpctl list firefox --since today
journalctl --since "10 minutes ago" | grep -E "firefox|SPA_VIDEO"

Check GNOME crashes:

coredumpctl list gnome-shell --since today
journalctl --since "10 minutes ago" | grep -E "gnome-shell|gvc_mixer|FATAL"

WirePlumber debug logging:

WIREPLUMBER_DEBUG=3 wireplumber &> ~/wireplumber-debug.log

Conclusion

This investigation revealed multiple interacting bugs in modern Linux audio/video infrastructure:

  1. V4L2 metadata devices breaking Firefox WebRTC
  2. Bluetooth profile switching crashing GNOME Shell
  3. Fatal assertions in production code paths

The solutions involve a combination of:

  • WirePlumber configuration to filter problematic devices and stabilize Bluetooth
  • Firefox configuration to use V4L2 directly instead of PipeWire
  • USB audio device optimization

While these are workarounds rather than fixes for the underlying bugs, they provide a stable system until upstream projects can implement proper error handling.

I hope this detailed investigation helps others experiencing similar issues with PipeWire, Firefox WebRTC, GNOME Shell, and Bluetooth audio on Fedora and other modern Linux distributions.


System Information

  • OS: Fedora 43 (CSB - Corporate Standard Build)
  • Desktop: GNOME 49 with Wayland
  • Audio: PipeWire 1.4.10 + WirePlumber 0.5.13
  • Firefox: 147.0.1 (Flatpak)
  • Hardware:
    • Logitech BRIO webcam
    • Integrated Camera (with IR)
    • Sony WH-1000XM4 Bluetooth headphones
    • Blue Microphones USB microphone

Configuration Files:

  • ~/.config/wireplumber/wireplumber.conf.d/99-hide-metadata-cameras.conf
  • ~/.config/wireplumber/wireplumber.conf.d/51-bluez-config.conf
  • ~/.config/wireplumber/wireplumber.conf.d/52-blue-microphones.conf

References and Documentation

This investigation relied on the following documentation and resources:

PipeWire and WirePlumber:

V4L2 and Video Devices:

Bluetooth Audio:

System Tools:

  • wpctl - WirePlumber control tool
  • v4l2-ctl - V4L2 device control utility
  • journalctl - systemd journal query tool
  • coredumpctl - Core dump analysis tool
  • pavucontrol - PulseAudio/PipeWire volume control

Bug Reports and Fixes:

GNOME Release Information:


End of Technical Report

Photo by Nathan Neve on Unsplash