CXEndCallAction fails with unknownCallUUID (Code=4) when app rejects/ends a call reported via CallKit

Summary:

When our VoIP app attempts to reject/end an incoming call, CXCallController.request(_:completion:) fails with: Error Domain=com.apple.CallKit.error.requesttransaction Code=4 "(null)"

CXErrorCodeRequestTransactionError, Code 4 = unknownCallUUID — the call UUID did not match a call known to the call kit. As a result, the Incoming call screen continue to displayed and leaving a stale/ghost call in CallKit.

Environment:

  • iOS version: 26 / 18
  • Device model: iPhone 14

Steps to Reproduce:

  1. Receive an incoming VoIP call (reported to CallKit via CXProvider.reportNewIncomingCall).
  2. Reject the call programmatically OR manual end call
  3. Observe: app-side call state transitions to ended/rejected, but the native CallKit call UI/state does not clear — CXEndCallAction request fails with unknownCallUUID.
  4. [fill in: reproduction rate — always / intermittent / specific timing window]

Full error log:

2026-08-13T13:41:16:902+0530 Thread 915 — [CallKitManager requestTransaction:]_block_invoke: Error requesting transaction:
[<CXTransaction 0x14f1eb060 UUID=E1785E55-24CF-49E6-8225-372E7F5F0F9D isComplete=0 actions=(
    "<CXEndCallAction 0x141d18190 UUID=BBE9EB13-EFF5-49F1-99DC-96A6218C9031 state=0 commitDate=(null) callUUID=7C8A16B2-4CF4-4F66-A588-5A663A6D52D4 dateEnded=(null)>"
)>]
Error Domain=com.apple.CallKit.error.requesttransaction Code=4 "(null)"

Questions :

  1. Can CXCallController.request(_:completion:) legitimately fail with unknownCallUUID if CXEndCallAction is issued before the reportNewIncomingCall completion handler has returned — i.e., is there a required ordering/synchronization guarantee we're missing?
  2. Are there known conditions (OS version-specific behavior, app suspension/background state, Do Not Disturb / Focus interaction, multiple concurrent CXProviders) under which CallKit's internal call controller can "lose" a UUID that was previously reported, causing a subsequent valid action to be rejected as unknown?
  3. Is there a supported way to query CXCallController/CXProvider for the current set of UUIDs it considers "known" at a given time, to diagnose this class of mismatch before issuing an action?
  4. Once unknownCallUUID occurs, is there a recommended recovery path to force-clear a stale call from CallKit's UI/state from the app side, short of ending all calls?
  1. Can CXCallController.request(_:completion:) legitimately fail with unknownCallUUID if CXEndCallAction is issued before the reportNewIncomingCall completion handler has returned — i.e., is there a required ordering/synchronization guarantee we're missing?

Theoretically, yes, though I think it would be difficult to do under real-world conditions. Communication between callservicesd and your app is entirely asynchronous, so if you immediately reported actions against an action, it's possible that action could be processed before the call was "live". However, I've never actually seen that happen, particularly not leaving the UI active*.

*The opposite race where the Call UI ends the call before your app "knows" it's ended is fairly common, but that never leaves the interface active.

Are there known conditions (OS version-specific behavior, app suspension/background state, Do Not Disturb / Focus interaction, multiple concurrent CXProviders) under which CallKit's internal call controller can "lose" a UUID that was previously reported, causing a subsequent valid action to be rejected as unknown?

As noted above, there are lots of cases where callservicesd can end up ending the call at the same time your app is sending actions to that call. However, none of those would leave the call UI active.

Is there a supported way to query CXCallController/CXProvider for the current set of UUIDs it considers "known" at a given time, to diagnose this class of mismatch before issuing an action?

You can retrieve the current call list with CXCallController.calls; however, be aware that it will return calls that are NOT your apps.

Once unknownCallUUID occurs, is there a recommended recovery path to force-clear a stale call from CallKit's UI/state from the app side, short of ending all calls?

I'm not sure as this is the first time I've heard of this. Are you able to reliably reproduce the issue with Speakerbox?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

CXEndCallAction fails with unknownCallUUID (Code=4) when app rejects/ends a call reported via CallKit
 
 
Q