CallKit UI not invoked after receiving VoIP Push – app killed with NSInternalInconsistencyException

Our VoIP app receives PushKit notifications successfully (callservicesd Delivering 1 VoIP payload appears in logs). However, the app is consistently terminated by the system when running in the background or killed state.

The crash is caused by iOS expecting a reportNewIncomingCall to CallKit, but the system reports:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push.'
*** Assertion failure in -[PKPushRegistry _terminateAppIfThereAreUnhandledVoIPPushes], PKPushRegistry.m:349

Key Observations: VoIP pushes arrive and are delivered to the app. In foreground, some methods work and CallKit UI sometimes appears. In background/killed state, app is always terminated before CallKit UI shows. Logs confirm the system requires CallKit to be reported immediately inside pushRegistry(_:didReceiveIncomingPushWith:for:completion:).

Steps to Reproduce: Run the app with VoIP + CallKit integration. Put app in background (or kill it). Send a VoIP push.

Observe system logs and crash:

callservicesd: Delivering 1 VoIP payload(s) to application UrgiDoctor: Apps receiving VoIP pushes must post an incoming call via CallKit... error: Killing VoIP app because it failed to post an incoming call in time.

Expected Behavior: On receiving a VoIP push, CallKit UI (Accept / Decline screen) should always appear. App should not be killed if reportNewIncomingCall is called in time.

Actual Behavior: CallKit UI never appears in background/killed state. App is force-terminated by iOS before user can accept/decline the call.

Request:

Guidance on the correct sequence for calling reportNewIncomingCall and completionHandler() in pushRegistry. Clarification if any changes in iOS 17/18 affect PushKit + CallKit behavior. Best practices for ensuring CallKit UI always appears reliably after a VoIP push.

Environment:

iOS 18.5 Simulator + Device

Xcode 16.4 Using PushKit + CallKit with VoIP entitlement

Let me start with the basic crash itself:

The crash is caused by iOS expecting a reportNewIncomingCall to CallKit, but the system reports:

The logic that triggers this crash is extremely simple. When reportNewIncomingCall is called, it sets a flag inside PKPushRegistry noting that a call has been reported. When you return from didReceiveIncomingPushWith, PKPushRegistry checks that flag and terminates your app if a call hasn't been reported. Nothing else will trigger this crash. For reference, this forum post has more specifics about the full architecture.

Guidance on the correct sequence for calling reportNewIncomingCall and completionHandler() in pushRegistry.

The sequence itself doesn't matter, nor does the completion handler. However, there is one issue tied to async functions that can cause problems. This thread on LiveCommunicationKit (which has exactly the same problem) describes the issue and solutions (make sure you read the entire thread).

Clarification if any changes in iOS 17/18 affect PushKit + CallKit behavior.

Nothing significant about this changed between iOS 17/18. Indeed, the only major change in this architecture was the introduction of the iOS 13 CallKit requirements.

Best practices for ensuring CallKit UI always appears reliably after a VoIP push.

This post describes my core advice for this, however, I'd also suggest looking over the rest of that thread for a good example of how these kinds of bugs happen.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

CallKit UI not invoked after receiving VoIP Push – app killed with NSInternalInconsistencyException
 
 
Q