Controlling Pipewire's Misconfigured Audio Output Sinks
One of the worst breakages from the *grade (I hesitate to call it an upgrade) to Debian Trixie was audio. The old PulseAudio setup — which had been working beautifully for the last several years — was replaced by a new sound system called Pipewire that sits on top of PulseAudio and, well, basically, breaks it.
Recently I decided it was finally time to figure out Pipewire's broken handling of audio output. The main problem: half the time, upon booting, my audio doesn't work, and if I run pavucontrol to see the configuration, I see three different HDMI audio devices as well as the laptop's built-in Intel audio chip. Most of the time my laptop is plugged in to an HDMI monitor, yes — but that monitor has no speakers or other audio hardware, so I basically never want HDMI audio. And in any case there's only one monitor connected, not three.
(And yes, there are occasionally times I might want HDMI sound, like if I want to give a presentation over a projector that uses sound. That has happened to me once in my life, so far.)
So every time I boot, there's a good chance that audio won't work and I'll have to fire up pavucontrol, go to the Output Devices tab, mute all three of the HDMI sinks, unmute the built-in speaker sink, and click the button to make the built-in speaker the default sink. (There's no way to tell what the previous default was: pavucontrol, although it has buttons to set a sink as default, doesn't show what the current default is.)
Terminology note: if you haven't worked with PipeWire or PulseAudio before, a "sink" is a place you can send sound to, like a speaker or an HDMI display.
Listing Sinks
It helps to have a quick way to see what sinks are available. PipeWire doesn't have its own tools for this, but it runs on top of PulseAudio, and if you install the pipewire-pulse package you can use some, but not all, PA tools to check the state of PW. For instance, pactl works but pacmd doesn't.
The easiest way to see the currently available output sinks:
pactl list sinks short
You can also use a WirePlumber command that gives much more verbose output.
WirePlumber is how you configure PipeWire, though it
wasn't installed by default on my system, so I had to
apt install wireplumber first. Then:
wpctl status
First Try: Blacklist the Module
I first tried blacklisting the snd_hda_codec_hdmi module, so the kernel couldn't load it (this turned out to be harder than expected; I'll write about that separately). Not a good solution. Logging in now took 30 seconds: apparently pipewire still thought there should be three HDMI devices and was trying to open them, and timing out because without the module it couldn't talk to them. Or something. There were also a ton of errors in dmesg like
[ 62.070132] snd_hda_codec_generic ehdaudio0D2: snd_soc_find_pcm_from_dai: didn't find PCM for DAI intel-hdmi-hifi1 [ 62.070157] snd_hda_codec_generic ehdaudio0D2: ASoC: error at snd_soc_dai_startup on intel-hdmi-hifi1: -22 [ 62.070177] iDisp1: ASoC: error at __soc_pcm_open on iDisp1: -22 [ 62.070188] HDMI1: ASoC: error at dpcm_be_dai_startup on HDMI1: -22 [ 62.070198] HDMI1: ASoC: error at dpcm_fe_dai_startup on HDMI1: -22repeated periodically. Seemed like it should have been a nice clean solution, but nope. Don't blacklist that module.
Second Try: Hide the ALSA path to the Sink
I found one page that suggested I could remove the HDMI sinks from /usr/share/alsa-card-profile/mixer/paths. That sounded like a great, and easy, solution, so I removed everything with HDMI from that directory, but alas, it didn't make any difference. I don't know what, if anything, uses that directory, but it's not PipeWire.
(Don't) Re-initialize WirePlumber State (and pavucontrol Profiles)
I ran across a page trying to solve the same problem — get rid
of all the dang HDMI sinks, which it turns out a lot of
people want to do — that suggested removing WirePlumber
state by removing ~/.local/state/wireplumber/ to let it
regenerate the state. Not recommended! Or at least,
if you do it, mv it somewhere rather than rm -rf.
I removed it, and that caused PipeWire to decide that my built-in
sound card only had Headphones, instead of only having Speaker. (Having
both at the same time doesn't seem to be an option in PipeWire: it can
have three nonexistent HDMI settings, but both Speaker and Headphones?
Forget that.)
My headphone jack is broken: years ago, when I bought the little amp I use with my big speakers, I initially tried to use them by plugging them in to the laptop's headphone jack. That didn't work well, but it did do something, maybe involving pumping too much power through, that caused the headphone jack to emit horrible white noise all the time, so it's no longer usable. So anyway, PipeWire's limitation on having only one or the other isn't that bad for me as long as it stays on Speaker, but if it switches to Headphones, that means I can't use sound.
The only way I've found to get PipeWire to see the Speaker again is from pavucontrol's Configuration tab. Apparently in the Configuration tab, some people see all sorts of useful things you can actually configure, but in mine, all I see is one menu, labeled Profile, where I can choose between four options:
- Play HiFi quality Music (HDMI1, HDMI2, HDMI3, Headphones, Mic1, Mic2)
- Play HiFi quality Music (HDMI1, HDMI2, HDMI3, Mic1, Mic2, Speaker)
- Pro Audio
- Off
Switching from the first option to the second makes PipeWire see the Speaker instead of the Microphone.
I haven't found anything about what pavucontrol is doing here that I might be able to duplicate from the command line without firing up a GUI program and clicking around every time PipeWire gets confused about whether to use Headphones or Speaker. pavucontrol's concept of Profiles seems to be unique to pavucontrol and maybe not even visible to pulseaudio, pipewire or wireplumber. Nobody seems to know what "Pro Audio" means, either.
What Finally Worked: Disable a Node in WirePlumber
I mentioned earlier that WirePlumber is how PipeWire is configured. Unfortunately, WirePlumber isn't well documented, and it changed its configuration syntax a year or two ago, so if you have WirePlumber 0.5 or later (which is likely) and you do any web searching, make sure you're not looking at an earlier page that uses the old lua syntax.
The WirePlumber documentation on the Arch Wiki is probably the best around, though there are other pages with a similar level of detail. Unfortunately, they're all incomplete.
The main problem is that everybody talks about how to disable a device — which apparently means a sound card — but they don't mention how to disable just a sink. In my case, the three HDMI sinks, the built-in speaker and the broken built-in headphone jack all come from the same Intel card, so disabling the card isn't an option.
The key nobody mentions is that a sink is considered a "node", and you can disable a node.
First, use pactl list sinks short and get the node names
of the sinks you want to disable: the names will be something like
"alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink".
Then create a file ~/.config/wireplumber/wireplumber.conf.d/hdmi-disable.conf (you can name it anything you want as long as it's in that directory) and put this in it:
monitor.alsa.rules = [
{
matches = [
{
node.name = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink"
}
]
actions = {
update-props = {
node.disabled = true
}
}
},
{
matches = [
{
node.name = "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI2__sink"
}
]
actions = {
update-props = {
node.disabled = true
}
}
},
]
with as many entries as you need to disable: three, in my case, but I left
off the third here because it's just like the first two.
You'll see pages suggesting you can use a wildcard or regular expression, like "alsa_output.*HDMI.*" or "alsa_output*HDMI*" (it's never clear which). That would be wonderful, since I don't have much confidence that names like "alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__HDMI1__sink" are going to stay unchanged for long. But wildcards and regexps didn't work for me, and I don't see them mentioned in any documentation or recent HOWTOS. I found a few suggestions that this used to work with the old lua format, but no longer works in the new format. Sigh. Maybe they'll add it back some day.
One More Thing: Be Ready to Restart Pipewire
Over the next several reboots, sound worked and my Speaker device remained the default so I didn't have to fire up pavucontrol. But then on the third day, no sound.
pactl list sinks short lists just the built-in speaker,
as I wanted, with no headphones or HDMI.
wpctl get-volume @DEFAULT_AUDIO_SINK@ said Volume: 0.68.
Initially it also said [MUTED],
but I ran wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
and the [MUTED] went away.
pavucontrol showed the device enabled, un-muted and with reasonable volume.
alsamixer showed the volume at 71. That all looked fine.
What else was there to check?
I don't know what else, or why there was no sound; but the solution was something I've found I have to do fairly frequently: restart pipewire.
systemctl --user restart pipewire pipewire-pulse wireplumber(no root needed). Sometimes PipeWire apparently just gets confused and fails to work, and restarting often fixes it. So keep that command in your grab bag if you're on a PipeWire system.
[ 16:37 Mar 22, 2026 More linux | permalink to this entry | ]