CallKit does not activate audio session with higher probability after upgrading to iOS 18.4.1

Hi,

We've noticed that this issue occurs more frequently after upgrading to iOS 18.4.1 and can result in one-way audio.

Our app uses CallKit with WebRTC to establish VoIP connections.

However, on iOS 18.4.1, CallKit no longer triggers:

func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession)

We're currently comparing the occurrence rate across different iOS versions to better understand the impact.

Could you please help analyze the root cause of this issue?

Answered by DTS Engineer in 862474022

One bit of follow-up on the bug fix side of this:

FB19429215 (CallKit does not activate audio session with higher probability after upgrading to iOS 18.4.1)

Having looked into the issue in more depth, there are technical issues that are likely to delay a fix coming from our side. The CallKit team is still committed to resolving this, but you should not expect the issue to be resolved in the short term.

I'll also say that, based on my own analysis, I do NOT think this is in fact a "new" issue. That is, going back to the original report on this thread:

We've noticed that this issue occurs more frequently after upgrading to iOS 18.4.1

The focus here was on the increased rate; however, it's very likely that this was simply a shift in the rate an existing bug occurred, NOT a new/different issue. Because of that, my recommendation is that all CallKit apps send a "setConfiguration" immediately before they report a new call. It's the best way I can see to prevent the problem from occurring and is already fully supported by the API, so it's unlikely to introduce new problems. This also means that this code can be left in place indefinitely, regardless of our own bug fix schedule. I strongly suspect that using this approach will improve overall call reliability across all system versions, not just our most recent releases.

*As I noted earlier, it's the only way to do per-call ringtone and icon customization.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

FB20789841 (CallKit does not activate audio session, the issue rate increased on iOS 26.)

I've looked over the sysdiagnose from that log and I'm left a bit confused. You said that you've applied the workaround I'd suggested, but when I look at the log you sent I don’t see the workaround I'd suggested. I can see where you're reporting calls:

2025-10-23 16:00:39.916170+1100 <exec>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was asked to report a new incoming call with UUID: <private> update: <private>
…
2025-10-23 16:01:34.063889+1100 <exec>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was asked to report a new incoming call with UUID: <private> update: <private>
…
2025-10-23 16:02:01.765404+1100 <exec>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was asked to report a new incoming call with UUID: <private> update: <private>

However, if the workaround was active I'd expect to see a log message like this before each of those call reports:

2025-10-23 16:00:39.916170+1100 <exec>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was notified that configuration was set to <private> update: <private>

...but I don't actually see evidence of ANY setConfiguration calls. Every indication in the log is that you setConfiguration when you initially connected and that logging was then lost due to purging.

What's particularly frustrating here is that there is every indication in the log that the workaround would have worked, as the core failure is the same as the other cases I've looked at:

2025-10-23 16:01:52.259438+1100 callservicesd: (AudioSession) [com.apple.coreaudio:as_client]     AVAudioSession_iOS.mm:597   Creating proxy session failed, session ID = 0x0, error = <NSError:0x60000071c03da10(NSOSStatusErrorDomain:-50) - {
    NSLocalizedDescription = "Session lookup failed";
}>

...and later in that same log, your app IS able to activate the AudioSession later in the same log, probably because of a direct "setActive" call while your app was in the foreground.

2025-10-23 16:01:07.946140+1100 callservicesd: [com.apple.calls.callservicesd:Default] Entered foreground for call with identifier <private>

2025-10-23 16:01:17.244642+1100 Glip: (AudioSession) [com.apple.coreaudio:as_client]     AVAudioSession_iOS.mm:984   Activated session 0xd387b18

Note that I'm particularly concerned about the workaround here because if the workaround I've suggested DOESN'T work, then that indicates a much deeper failure in the audio system that CallKit may not be able to address.

If you're able to reproduce the issue with the workaround, please provide a sysdiagnose showing that failure, ideally with the FaceTime debugging profile installed.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

@DTS Engineer Thank you for reviewing the logs. Upon examination of the solution, we discovered that it was not implemented as expected. Specifically, we did not call setConfiguration before reporting incoming calls each time. We will re-implement the workaround solution, and it will require additional time for verification.

@DTS Engineer Thank you for reviewing the logs. Upon examination of the solution, we discovered that it was not implemented as expected. Specifically, we did not call setConfiguration before reporting incoming calls each time. We will re-implement the workaround solution, and it will require additional time for verification.

Fair enough, and please let me know if/when you have results from the setConfiguration workaround I suggested. As I noted in my previous message, if my workaround doesn't work, then that invalidates my entire theory about what's going on and the fix I've recommended.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

@DTS Engineer

Sure, will do.

We have re-implemented the workaround solution and plan to roll it out to production in two weeks. Before proceeding, could you please help double-check if the workaround is implemented as expected in our lab app? Thank you for your assistance.

Sysdiagnose log file sysdiagnose_2025.10.28_18-28-20_0800_iPhone-OS_iPhone_23A355.tar.gz has been uploaded in the ticket.

FB20789841 (CallKit does not activate audio session, the issue rate increased on iOS 26.)

Before proceeding, could you please help double-check if the workaround is implemented as expected in our lab app?

Yes, that looks correct. Here is one incoming call report flow from that sysdiagnose:

2025-10-28 18:27:47.401604 callservicesd: [com.apple.calls.callservicesd:Default] Received incoming APS message from application with bundle identifier <private> and topic <private>
2025-10-28 18:27:47.454707 callservicesd: [com.apple.calls.callservicesd:Default] Successfully launched application with bundle identifier <private>
2025-10-28 18:27:47.459960 callservicesd: [com.apple.calls.callservicesd:Default] Delivering 1 VoIP payload(s) to application <private>

CXProvider set configuration:
2025-10-28 18:27:47.476283 <app>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was notified that configuration was set to <private>
2025-10-28 18:27:47.476350 <app>: (CallKit) [com.apple.calls.callkit:Default] Registering configuration <private>
2025-10-28 18:27:47.477213 callservicesd: (CallKit) [com.apple.calls.callkit:Default] Received -[CXCallSource registerWithConfiguration:] with configuration: <private>

CXProvider reportNewIncomingCall:
2025-10-28 18:27:47.478526 <app>: (CallKit) [com.apple.calls.callkit:Default] Provider <private> was asked to report a new incoming call with UUID: <private> update: <private>
2025-10-28 18:27:47.478814 callservicesd: (CallKit) [com.apple.calls.callkit:Default] Received -[CXCallSource reportNewIncomingCallWithUUID:update:reply:] with UUID: <private> update: <private>

...which is exactly what I'd expect.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

@DTS Engineer Thank you for the confirmation.

It will take at least another two weeks before we roll out to production. We will monitor the effectiveness of the workaround and provide the results here.

Anyone with any luck fixing/improving this ?

Anyone with any luck fixing/improving this ?

Are you calling "setConfiguration" before each call report as I suggested here?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi @DTS Engineer,

In my practice dealing with CallKit I came to conclusion that changing CXProvider configuration during a call is a bad idea. Sometimes this was causing providerDidReset being called and first call got dropped. Can you confirm or deny my observation? Do you suggest to call setConfiguration even there is an other active call or call on hold?

In my practice dealing with CallKit, I came to the conclusion that changing CXProvider configuration during a call is a bad idea. Sometimes this was causing providerDidReset being called, and the first call got dropped. Can you confirm or deny my observation?

That's hard to say. On its own, I wouldn't expect it to be an issue or, more specifically, it's much more likely to "trigger" a pending failure than it is to create one. As background context, the primary cause of providerDidReset is mediaserverd itself crashing, not "normal" system behavior. I'm sure there are cases where a call to "setConfiguration" was the direct "trigger", but that doesn't mean that NOT calling "setConfiguration" would have prevented the crash. It's also possible/likely that "setConfiguration" DID actually "cause" providerDidReset... because the media system was already in a bad state, and the setConfiguration call is what caused callservicesd to detect a problem.

However, having said all that...

Do you suggest calling setConfiguration even if there is another active call?

There's no reason to call setConfiguration if you already have an active call. One thing to keep in mind here is the difference between the "call" abstraction CallKit provides and the actual behavior of the audio system. Your app only has one "connection" to the audio system, no matter how many calls you have active. An action like switching from one of your calls to another call changes call state, but it doesn't really affect the audio system. As far as the audio system is concerned, your app is just sitting there with an active session.

or call on hold?

This case is a little bit more “grey," but no, I probably wouldn't bother. Jumping back to my original analysis here:

"No, it can't. It's possible that it may mask the issue in some cases; however, it's also very likely to introduce failures somewhere else. In any case, in terms of what the real problem is, the key issue is the "SessionID 0x0" here: ... That session ID is the global identifier callservicesd uses to "find" your app’s audio session so that it can manage and activate it. It's not explicitly set by your app because it's actually included in the configuration payload you configure (and modify) CXProvider with. I'm not sure how it became NULL, but if I had to guess, it was either a side effect of an out-of-order process initialization (creating CXProvider prior to main) or a side effect of a system-wide disruption that wasn't handled properly."

Something that may not be obvious from that analysis is that the issue here is about recovering from a previously bad state, not actually "being" in a bad state. Putting that in more concrete terms, the "setConfiguration" workaround works because it's retrieving a valid session ID from your app and passing it over to callservicesd. The only reason that would "fail"... is because the audio system isn't working properly. If you "know" the audio system is working correctly, then there isn't really any reason to call setConfiguration.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hi @DTS Engineer

Apologies for the delayed update. Yesterday, we completed the rollout of your workaround solution, and our metrics indicate its effectiveness. The issue count has decreased significantly during the implementation, dropping from 6000 per day to 1000 per day as of today.

We would like to express our gratitude for the workaround solution you provided.

Currently, we have implemented the workaround only for incoming calls, as these were the primary source of issues observed in our app. We plan to extend the implementation to outbound calls as well. Any other suggestions for this process would be greatly appreciated.

Apologies for the delayed update. Yesterday, we completed the rollout of your workaround solution, and our metrics indicate its effectiveness. The issue count has decreased significantly during the implementation, dropping from 6000 per day to 1000 per day as of today.

Fabulous, that's great to hear and thank you for sharing concrete numbers. I was fairly confident it would work, but it's good to get independent confirmation.

We would like to express our gratitude for the workaround solution you provided.

You're very welcome.

Currently, we have implemented the workaround only for incoming calls, as these were the primary source of issues observed in our app. We plan to extend the implementation to outbound calls as well.

I don't know this for certain, but my guess is that the difference between the incoming/outgoing rate is mostly due to usage patterns and the details of your existing implementation. In particular, these two factors:

  1. I suspect most calls originate from the foreground (the user opening your app and picking the person to call).

  2. I suspect you're still calling "setActive", despite my earlier cautions against doing so.

Those two factors together will "mask" the entire problem. That is, CallKit activation will still fail for exactly the same reason but #2 will succeed, masking the problem.

There's also a secondary effect at play here where applying the workaround on one call will change the behavior of later calls. In other words, if your app gets into the broken state but that receives an incoming call, the setConfiguration of that incoming call is very likely to "fix" the behavior of future outgoing calls.

Any other suggestions for this process would be greatly appreciated.

So, I definitely apply it to outgoing calls as well. It's a very low-risk workaround, so there isn't really any reason not to. Once you've got the fix into full release for all call types, I think the next step would be to try and get a sysdiagnose from whatever failures are left. My guess is that any remaining failures will either involve EXTREMELY specific timing (for example, mediaserverd crashing IMMEDIATELY after you call reportNewIncoming) or actually involve something completely different than what I've seen here.

Just make sure you've applied the setConfiguration fix "everywhere" before you file new bugs or spend too much time digging into this. It's already taken a big bite out of your failure rate, and I'd expect it will do even more when fully applied.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

CallKit does not activate audio session with higher probability after upgrading to iOS 18.4.1
 
 
Q