CarPlay: CPListItem.image degrades to placeholder glyph mid-session, only iPhone reboot recovers — FB22828125

Posting here in case other CarPlay developers are hitting the same thing, and to give Apple engineers a forum-side reference for the radar.

Filed as FB22828125.

Symptom

In a CarPlay app using CPListTemplate, UIImage instances assigned to CPListItem.image start rendering as the system placeholder glyph after extended CarPlay use (several hours to a few days of cumulative session time). Text labels and accessory chevrons still render correctly — only the leading image is affected, and it affects every visible template surface at once.

Known recovery

Once the failure starts, it survives:

  • Killing and relaunching the app
  • Force-quitting and relaunching from CarPlay itself
  • Disconnecting and reconnecting CarPlay

The only known recovery is rebooting the iPhone. After reboot, the same code path renders correctly again — until the failure reoccurs.

App-side ruling-out

  • UIImage instances passed to CPListItem.image are non-nil at failure time (verified by assertions)
  • Each template rebuild calls UIGraphicsImageRenderer afresh from UIImage(systemName:) — no caching of UIImage across rebuilds
  • Images are baked via withTintColor(_:renderingMode: .alwaysOriginal) then rasterized, so CarPlay receives a finished bitmap rather than a template image relying on its tinting pipeline
  • Same code path renders correctly on launch and for hours afterward — the input bytes are identical before and after the failure boundary

Because the failure survives both the app process and the CPTemplateApplicationScene teardown, the corrupted state appears to live in an iOS system process rather than in the app or the CarPlay session.

Question for the forum

Is there a known workaround on the app side — a different image-supply API, or a way to force the CarPlay rendering pipeline to invalidate its cache without an iPhone reboot?

Thanks for the FB number, looks like was submitted today?

You can see the status of your feedback in Feedback Assistant. There, you can track if the report is still being investigated, has a potential identifiable fix, or has been resolved in another way. The status appears beside the label "Resolution." We're unable to share any updates on specific reports on the forums.

For more details on when you'll see updates to your report, please see What to expect after submission.

Every time you generate a brand new bitmap via UIGraphicsImageRenderer and pass it to a CPListItem, the system treats it as a unique asset and sends a new bitmap. Over several hours of template rebuilds, the remote CarPlay process I would implement an app-side cache a simple dictionary for your images. If you need a specific icon with a specific tint, generate it once, cache it, and pass that exact same UIImage pointer to the CPListItem on subsequent rebuilds. The system is much better at optimizing identical object.

You mentioned you are baking the tint color into a bitmap using UIGraphicsImageRenderer Instead of rasterizing, apply the color. When you pass a symbol-configured UIImage to CarPlay, the XPC payload is tiny. It just sends the string name of the symbol and the color parameters, and the system daemon renders it natively on the CarPlay side.

Moving away from continuous bitmap generation and relying on cached images or native SymbolConfiguration payloads is in my opinion the best way to do this.

Albert
  Worldwide Developer Relations.

Thank you, yes that FB was submitted earlier today.

Two new pieces of data from a tester conversation today that I wanted to put on the record here, because they suggest the asset-accumulation theory may not be the whole story.

1. Cliff transition, not gradual degradation. I just spoke with one customer and he described the failure as "one second the screen was fine, the next it was gray boxes." Not a slow boil where one icon becomes the placeholder, then a few more, then most. Sudden onset, every visual at once.

2. Both CPListItem icons and CPListImageRowItemRowElement images fail. I have several list-row icons (connection status, adapter status) and the row-element images on my Driving and Charging tabs (which are CPListTemplates built with CPListImageRowItem rows).

  • The CPListItem rasterized SF-symbol icons are quasi-static. They're gated behind state-change snapshots and only re-rasterized on actual state transitions (connectionDisplay returning a different (symbol, tint) pair, or the adapter-action row flipping between connect/disconnect). Over a multi-hour drive the set of distinct visuals shipped from those sites is small — roughly 10 unique (symbol, tint) pairs total, repeated as the user moves through states.
  • The CPListImageRowItemRowElement images on the Driving and Charging tabs are high-churn by orders of magnitude. For example, the RPM gauges may produce hundreds of distinct bitmaps over a single drive — and there are several other continuously-varying gauges and sparklines feeding new bitmaps to other row elements several times per second.

Both surfaces are CPListTemplate image surfaces and presumably share the same Apple-side rendering code path. If the theory were "table fills up," I might imagine that the high-cardinality surface might degrade first, long before the quasi-static surface with ~10 distinct visuals could possibly contribute. Instead both surfaces appear to fail simultaneously.

That symptom shape — sudden onset, everything at once, survives app relaunch and CarPlay disconnect, only iPhone reboot recovers — reads more like a process-level fault on the iOS side (a crash, an XPC channel break, a watchdog trigger in carplayd or the render server) than a soft-limit being reached.

I'm working with affected testers/customers -- hoping one of them can capture a sysdiagnose.

Thank you for uploading the sysdiagnose today. This is very helpful.

You can see the status of your feedback in Feedback Assistant. There, you can track if the report is still being investigated, has a potential identifiable fix, or has been resolved in another way. The status appears beside the label "Resolution." We're unable to share any updates on specific reports on the forums.

For more details on when you'll see updates to your report, please see What to expect after submission.

Albert
  Worldwide Developer Relations.

Thanks — understood on tracking status via Feedback Assistant and that you can't discuss specific reports here. Adding two findings from analyzing the captured sysdiagnose(s) to the record, since they sharpen the "process-level fault" reading from my last post.

  1. We caught a process-level fault directly. In one capture, the shared CarPlay template host (CarPlayTemplateUIHost) was killed by the watchdog:

    0x8badf00d — "scene-create watchdog transgression: ... exhausted real (wall clock) time allowance of 10.00 seconds" (~10.8 s application CPU in the window).

The hung thread is the host's main thread, and it's CPU-bound (TH_RUN, no lock wait — not a deadlock). Symbolicated against iOS 26.5 (23F77):

-[CUIMutableStructuredThemeStore renditionWithKey:usingKeySignature:] -[CUICatalog _imageWithName:…] -[UIImageAsset imageWithTraitCollection:] -[CPImageSetAssetRegistration initWithLightImage:darkImage:…] -[CPListImageRowItemElement image] -[CPSImageRowCell configureWithImageRowItem:…] (during list population)

So the host saturates the main thread inside CoreUI image-rendition resolution while building a CPListTemplate. We hand over pre-rasterized UIImages, so the cost is host-side CUICatalog / UIImageAsset resolution — which is the same code path behind both CPListItem and CPListImageRowItem surfaces. That shared path is, I think, why both surfaces fail together (my point #2 last time) and why onset is a cliff rather than a gradual fill (point #1): it's one shared component faulting, not N assets accumulating.

  1. There's also a non-crash, self-healing variant. A second capture — a different user, different device (iPhone 16 Pro), on iOS 26.6 beta (23G5028e) — shows the same glyph symptom but with NO host crash: the host ran continuously under one PID, and the glyphs self-healed after ~1 hour without a reboot. The only icon-side artifact in that capture is com.apple.iconservices logging "Failed to create placeholder image … Fallback type: public.item."

Taken together: the recovery behavior spans a range — transient/self-heal in one capture, a host watchdog-kill in another, and (as others in this thread have described) reboot-required in the worst case. What's consistent across all of them is failed CoreUI image-rendition resolution, not asset accumulation — which lines up with the cliff-onset, both-surfaces-at-once, survives-relaunch shape.

This is now reproduced across two devices and on both iOS 26.5 (release) and 26.6 beta, so it's present in the current beta. I'll keep the FB updated as testers capture more sysdiagnoses.

One general question (not about the report status): for image-heavy CPListTemplate surfaces, is there any recommended app-side mitigation to reduce scene-create watchdog exposure or CUICatalog/UIImageAsset pressure — e.g., a supported way to hand images to the host that bypasses per-cell rendition resolution? Happy to take that to a separate thread if better.

CarPlay: CPListItem.image degrades to placeholder glyph mid-session, only iPhone reboot recovers — FB22828125
 
 
Q