I have a Raspberry Pi 5 driving a widescreen display in a project car, and I wanted wireless Apple CarPlay on it. Not through a head unit, not through an app on a phone propped in a cup holder, but rendered natively on the Pi so it lives inside the rest of my car software. The hardware for this is well trodden: a Carlinkit "Autobox" USB dongle does the actual CarPlay handshake with the phone over Bluetooth and Wi-Fi, and an open source receiver on the Pi decodes the H.264 video the dongle produces and shows it on screen.
It did not work. It connected, and then it showed nothing. I spent a long night on it, and I want to write down exactly what was happening, because the failure is specific, the internet is full of people hitting the same wall right now on iOS 26, and most of the advice you will find sends you in the wrong direction (usually toward reflashing dongle firmware you should not touch). If you searched for something like "Carlinkit connects but no video on Raspberry Pi" or "CarPlay black screen iOS 26," this is for you.
The exact symptom
Here is the signature, because matching it is how you know you have this problem and not a different one:
- The dongle is detected on USB. The receiver app opens it fine.
- The iPhone pairs over Bluetooth. It joins the dongle's Wi-Fi. iOS shows the "Use CarPlay" prompt and you accept it.
- A CarPlay session opens. On the Pi you see the receiver's own "connecting" screen.
- And then nothing. No video frame ever arrives. After roughly fifteen to thirty seconds the dongle gives up and drops both the Bluetooth and Wi-Fi links, and the whole thing loops.
The tell, once you can read the dongle's own status messages, is that the phone's reported OS version stays empty. The dongle knows your phone's Bluetooth name and MAC. It reports that Wi-Fi is available and the phone type is CarPlay. But the field where it should record the connected phone's iOS version never fills in. The CarPlay session is being negotiated and then abandoned before the phone commits to streaming.
What it is not (this part saves you the most time)
My first instinct, and the instinct in most forum threads, was that the fix must be a firmware update on the dongle. It is not, and chasing that is how people brick perfectly good hardware. Three things to rule out immediately, all of which cost you nothing:
It is not the dongle firmware. The Carlinkit CPC200-CCPA I was using was already on the newest firmware that publicly exists. There was nothing newer to flash to, only an older build. Flashing carries a real brick risk for zero possible gain. If your unit is on a recent 2025 build, skip this entirely.
It is not your phone. The widely reported iOS 26 CarPlay breakage was addressed by Apple in the early point releases, so a current iOS is fine. Siri being enabled is a genuine requirement for wireless CarPlay, so confirm that, but if Siri is on and you still get no video, the phone is not your problem.
It is not the physical connection. Bluetooth pairs, Wi-Fi joins, the session opens. All the transport layers are healthy. The dongle is doing its job.
The problem is the receiver software on the Pi, and specifically whether its implementation of the CarPlay session handshake is current enough for iOS 26. That is the entire story.
Why the popular receiver fails
The most commonly recommended open source CarPlay receiver is an Electron app built on a library called node-carplay. It is what most Raspberry Pi CarPlay guides point you at. On a current Linux desktop with a recent iPhone, it has real trouble, and I found and worked around three separate bugs in it before concluding it was a dead end:
- It calls a macOS only Electron API during window setup. On Linux that call throws, and the exception aborts the rest of the setup routine, including the code that wires up USB. So the dongle is never even looked for. This one I patched.
- It relies on the browser's WebUSB permission model but never actually calls
requestDevice(), so the dongle is never granted to the page and its device list comes back empty forever. I ended up force granting it over the Chrome DevTools Protocol with a synthetic user gesture just to get past it. - It renders the decoded video with WebGPU, which the Raspberry Pi 5's GPU cannot provide. I patched it to fall back to WebGL.
And after all of that, with every one of those bugs fixed, the result was the same: the phone connected, and no video ever came. Which was actually the most useful result of the night, because it proved the bugs were not the real issue. The real issue was upstream of all of them: the CarPlay session negotiation itself, and that library's version of it does not complete with iOS 26.
How I proved where it was failing
The thing that turned this from guessing into knowing was instrumenting the actual data. Two techniques worth stealing if you ever debug something like this:
Read the app's internal message bus. The receiver does its work in web workers. Using the Chrome DevTools Protocol I attached to those workers at runtime and wrapped their message ports with counters, so I could watch, live, exactly which message types were flowing. That is how I could state with certainty that status messages were arriving but that not a single video-data or audio-data frame ever did. The phone was connected and simply declining to stream.
Tee the raw USB traffic. The dongle talks to the host over a USB bulk pipe. I wrapped the USB read call and dumped every small inbound payload as text. That is how I got the dongle's own words: its model and firmware string, the Wi-Fi channel, the phone's name and MAC in the paired device list, and the status blob with that empty OS-version field. When the device tells you in its own protocol that the phone never finished connecting, you stop blaming your renderer.
A second native receiver I tried gave me the other crucial clue. It connected, and it stayed connected without dropping, where the Electron app had been flaky. The difference was that it enabled the dongle's encrypted USB protocol. Carlinkit added optional AES encryption to the host protocol in 2024 firmware, and receivers that do not speak it get a less reliable link. That still did not produce video, but it told me stability and the handshake were two separate problems, and that the handshake was the one that mattered.
The fix: use a current receiver
The answer, in the end, was not clever. It was to use the one receiver whose CarPlay session implementation is current: LIVI, an actively maintained head unit for Linux, macOS and Windows with a native GStreamer video pipeline. It explicitly supports the CPC200-CCPA, and it has iOS 26 specific handling that the older stacks do not. I downloaded its ARM64 AppImage, pointed it at the same dongle and the same phone, and CarPlay streamed on the first connect. Real maps, real navigation, real audio, on the Pi.
So the honest headline is this: if CarPlay connects but shows no video on your Raspberry Pi with a Carlinkit dongle and a modern iPhone, the receiver software is stale. Switch to a maintained one and it works. The dongle, the firmware, and the phone were never the problem.
The Raspberry Pi 5 gotchas nobody warns you about
Getting video was not quite the finish line. A few things about the Pi 5 specifically are worth knowing, because they cost me time and they are not written down anywhere obvious:
The Pi 5 has no hardware H.264 decoder. The Pi 4 had one; the Pi 5 dropped it and only decodes H.265 in hardware. CarPlay streams H.264. So on a Pi 5, CarPlay video is decoded on the CPU. It handles a widescreen stream fine, but it is about one full core of load, which matters if you are running anything else on the display at the same time. I freeze my other on screen app while CarPlay is up so the decoder has the headroom, and it stays smooth.
Do not hard kill the receiver. Sending SIGKILL to the receiver while it has the dongle open leaves the dongle wedged. It falls off the USB bus entirely and needs a physical unplug to come back. Always stop it with a normal terminate so it releases the device cleanly. Learned that one the annoying way, twice.
USB permissions and the re-enumeration race. The dongle re-enumerates constantly, its USB device number climbing every time the receiver opens it. A udev rule granting your user access to the device is required, and even then the receiver can briefly try to open it during the split second before the rule applies and log a permission error. It recovers, but do not panic when you see one at startup.
Credit where it is due
None of this is my discovery. The people who reverse engineered the Carlinkit host protocol, the maintainers of node-carplay and the receivers built on it, and the LIVI project that actually made iOS 26 work, did the hard part. What I can add is the map: the precise failure signature, the proof that it is the receiver and not the dongle or the phone, and the Raspberry Pi 5 specifics. If that saves one person from a night reflashing firmware they never needed to touch, it was worth writing down.
The next piece I am working on is more interesting than just showing the CarPlay screen: pulling the live media, navigation and call data out of the CarPlay session and drawing it into my own dashboard, the way a factory car shows now-playing and turn-by-turn on the instrument cluster while CarPlay lives on the center screen. It turns out the receiver already exposes all of that. That is a post for another day.