Your Joy-Cons are Vibrating Themselves to Death
I call it death by rumble: when your Nintendo controller disconnects mid-game on Linux. It’s the result of the unholy trio of Bluetooth, rumble, and gyro. Here’s why it happens, and what you can (probably) do about it.
Some of you may own a Nintendo Switch—and with it, a pair of Joy-Cons (they come in the box). Maybe later you picked up a Pro Controller, for more serious gaming. At some point, you might’ve decided to use these controllers on your PC, finding that Steam Input supports them, with full gyro, rumble, and button mapping, right out of the box.
It is a pretty solid setup—until it isn't.
If you've ever been deep in a game, sniping with gyro aim, racing through a high-intensity section, or just generally moving and rumbling at the same time, and your controller suddenly disconnects. You’re not alone.
It turns out, the Joy-Con can literally shake itself off the Bluetooth connection. Thanks to a very cursed combination of Bluetooth power profiles, Broadcom-Nintendo firmware code, gyroscopes, and your hostname (Yes, really Nintendo wants your hostname to use a Joy-Con).
BLE Sniff Mode: The Quirky Fallback
Thanks to reverse-engineering efforts, we know that when a Joy-Con or a Pro Controller connects to a host via Bluetooth, it actually checks the host's Bluetooth hostname. The firmware uses a memcmp against the beginning of hostname string, checking for:
- "Nintendo Switch"
- "NintendoRobson" (Robson is the internal codename for the Broadcom BCM4356XKUBG, the Switch's radio chipset)
- "Nintendo"
If the hostname matches one of the first 2 cases, the controller switches to its native HID mode—the same mode that it uses to connect to a real Switch. This mode has a different HID report format:
0x3F == GenericInputReportand runs in active mode, a full-power connection with maximum bandwidth.
If all the cases do not apply, the controller falls back to sniff mode, a Bluetooth low-power mode where the device listens at reduced intervals to save energy. It doesn't send periodic keepalives, expecting the host to send traffic often enough to keep the connection alive.
This works fine in most situations—but things start to break down when you send too much data.
Rumble Engaged
Rumble is one of those features you don’t think twice about until it becomes a problem. Most modern games use it constantly: off-roading in Forza Horizon, collisions in GTA V, or just about anything in Mario Kart 8 Deluxe.
When the game says “vibrate,” the controller vibrates. Simple enough, right? It is until you realize that rumble has physical effects.
IMU Spikes: The Controller Shakes Itself to Death
Joy-Cons and Pro Controllers have a built-in inertial measurement unit (IMU) for gyro aiming and motion controls. While great for precision movement, it also reports its own rumble vibrations as motion.
When the controller rumbles, the IMU picks up the movement and dutifully sends that data to the host—but the firmware can’t tell the difference between “player moved” and “controller shook itself". So what should’ve been a brief vibration now triggers a flood of motion reports: Bluetooth meltdown.
Now you've got:
- Outgoing IMU data (at high frequency)
- Incoming rumble commands
- Input poll reports to keep the connection going
Bluetooth sniff mode just simply isn't built for all of that. Packets get dropped or delayed, and the Bluetooth stack can't keep up with all of that.
Here's what happens:
- Rumble activates the vibration motor.
- The controller's IMU (gyroscope + accelerometer) detects the vibrations.
- The IMU floods the host with motion data in response.
- Meanwhile, the host also sends rumble packets back to the controller.
- All this traffic on a sniff-mode connection saturates the available bandwidth.
Because the controller can’t transmit all the IMU reports in time, the reports start queuing up. Eventually, the connection gets so clogged that the controller misses expected traffic from the host (e.g., input polls). The controller assumes the connection is dead and disconnects.
We can actually see this in syslog reports:
Jan 13 20:06:29 Archer kernel: nintendo 0005:057E:2009.0006: compensating for 4 dropped IMU reports
Jan 13 20:06:33 Archer kernel: nintendo 0005:057E:2009.0006: compensating for 5 dropped IMU reports
...
Jan 13 20:06:58 Archer kernel: nintendo 0005:057E:2009.0006: timeout waiting for input reportThis shows exactly what we'd expect from bandwidth exhaustion; queued reports piling up until the controller gives up.
This Happens When You Need the Controller the Most
That’s what makes this issue truly cursed: it doesn’t happen randomly or during idle time. It hits at exactly the worst moment:
- You're gyro aiming while under fire from enemies in a Steam Input game? Disconnected.
- Using Steam Haptics? Disconnected
- Using rumble in any game? I give it 2 minutes.
This is hardware, physics, and firmware all turning against you—because you're using the controller as intended.
The Workaround(s)
If you've read to this point, you may already have some ideas on where this is going. Yes, they're either very cursed or very inconvenient.
Change your Hostname (No, really)
As you have read, the controller firmware checks the hostname beginning with a specific substring, so what we can do is just change your Bluetooth hostname to anything that starts with the "Nintendo" prefix:
sudo bluetoothctl
# Inside the bluetoothctl shell
power on
system-alias "Nintendo"This tricks the controller into passing into its third hostname condition: Use the non-Switch controller profile, in Active mode.
Funnily enough it is somewhat viable to write a BlueZ plugin (or even just patch BlueZ itself) to accommodate for this quirk—prepending the substring "Nintendo" to your hostname when Joy-Cons or Pro Controllers are being connected. Thanks to Sega, Nintendo can't do anything about it. That's right: Sega does what Nintendon't.
Use USB-C Instead (For the Pro Controller)
If don't want to deal with the Bluetooth bullshit entirely, a reliable workaround is to simply connect your Pro Controller via USB-C. This solution works as the Pro Controller has a separate HID protocol for talking directly through USB, you can even use it on your Switch at the cost of the NFC reader (I mean, not many people collect amiibo anyway).
But now you've got a cable to deal with.
Downgrade to Bluetooth 4.0 (YMMV)
Another possible solution is to simply use a Bluetooth 4.0 adapter instead. This is usually a suggested solution on forums like Reddit because Switch controllers use Bluetooth 3.0 (Bluetooth Classic), which Bluetooth 4.0 has better compatibility with than Bluetooth 5.0. It's unproven to work but some people say it might be worth a try.
Conclusion
This whole mess is what happens when motion sensors, vibration motors, and wireless protocols collide in a firmware that was never tested outside its own ecosystem. Nintendo’s own hardware tolerates it because they built the whole stack. Linux doesn’t get that luxury.
So yes—your Joy-Con is literally shaking itself off the connection.
If you’ve experienced mysterious disconnects mid-game, now you know why. And maybe until someone implements a proper fix for this, you may want to just use USB-C, an Xbox controller or even a PlayStation controller for gaming on Linux for now.
Comments ()