Keychain write errSecNotAvailable

What could cause the errSecNotAvailable error (-25291) to be returned from a keychain write? I see from the documentation "No trust results are available," [1]. Is that something that can be remedied on a retry of the same keychain query, is there some action that can be taken to fix the error programmatically, or does the user have to do something on the device to fix this? I see one comment indicating the device would need to be restarted [2].


[1] https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/#//apple_ref/c/econst/errSecNotAvailable

[2] http://fossies.org/linux/fpcbuild/fpcsrc/packages/univint/src/SecBase.pas

Replies

Which platform (iOS or OS X)?

If it's OS X:

  • Is this talking to iCloud Keychain (via the 'synchronizable' flag)?

  • Is your app sandboxed?

  • Is your app building for the Mac App Store?

The reason I ask is that iOS and OS X have radically different keychain implementations, except when it comes iCloud Keychain, where the OS X implementation is very similar to the iOS one. So, the first step of investigating any mystery keychain problem is to figure out which implementation you're talking to.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

This is on the iOS platform.

In the iOS keychain implementation

errSecNotAvailable
is returned for a bunch of reasons, mostly related to unexpected internal errors. I would not expect to see this as a result of you using the API incorrectly.

Earlier you wrote:

… does the user have to do something on the device to fix this

That's my immediate suspicion but really I'm just speculating at this point. What's the context for your question? Are you seeing reports of this coming back from the field? When it happens, do you see anything interesting in the device's system log?

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

eskimo, thanks for your responses.


We store important information regarding our users login status shared across a suite of apps in the keychain. We raise exceptions when we get unexpected statuses back from the keychain queries, as the user cannot be allowed to log in without checking the login status in the keychain. We have seen a few crashes with this status. However, it appears the user has been able to successfully get past it within the next 5-10 min after the app restarts. I'm not sure if there's anything the user has done to fix the issue in that time. So I'm curious if we should handle this status and retry the keychain query (as in it's a transitory error that can correct itself within the life of the app), or present the user with an alert advising them to restart the app or device (as in there's something wrong with the application/device state that needs to be restarted before it can be resolved).


This has only happened in the field and we only receive our own custom crash reports, so I don't have much more information for you to go on, or any system logs.

We had been seeing this in the field as well. However, I thought Apple had fixed this issue in iOS 7? I remember talking to Quinn at WWDC who advised me that we should be able to use the keychain after 200ms after launch of the app? I'm confused there because it seems like if I try to read/write from the keychain on the very first line of my AppDelegate, I am able to read/write from the Keychain without issue on test iPod and iPhones.

However, I thought Apple had fixed this issue in iOS 7? I remember talking to Quinn at WWDC who advised me that we should be able to use the keychain after 200ms after launch of the app?

I think you must be mixing me up with someone else. AFAICR I've never advised folks to delay accessing the keychain by 200 ms, for this or any other issue.

Also, are you sure you're not confusing this error with the -34018 (

errSecMissingEntitlement
) issue? Folks have been suggesting that delaying their keychain access might work around -34018 issue, although personally I don't think that actually helps.

This -34018 issue is covered in this DevForums thread.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Most keychain errors also log a detailed explanation in the console. It would really help to get the console log from an affected customer when they report the errSecNotAvailable error.


--gc

We are trying to obtain logs for this but it's proving to be quite challenging. Please stay tuned.

I'm getting this error too, for MacOS.

I'm using keychain for iOS and MacOS VPN (network extension) apps, and recently I got few app crashes involving save password to keychain.

The crashes are only on my MacOS app, even this code is used for both platforms.

The code is taken from Apple example (SimpleTunnel).

What's could be the cause to this error? And how can I fix it?

I have logs for that case. We have a problem in that area.

Some users are complaining that their FaceID unlock does not work.

We store a password in the keychain using the secure enclave with FaceID.


When we want to read the value in the keychain, FaceID normally shows up. But now an error pops up with the following OSStatus:

-25291


The user sent us console logs. I narrowed the logs down to the relevant block of logs for this issue, I think. Looks like this:


standard12:13:34.435678+0100securitydAuthentication is needed for genp,rowid=20311 (-25330): Error Domain=NSOSStatusErrorDomain Code=-25330 "(null)"
standard12:13:34.435857+0100securitydAuthentication is needed <OURAPP>[5905]/1#6 LF=0 copy_matching Error Domain=NSOSStatusErrorDomain Code=-25330 "(null)"
standard12:13:34.437637+0100coreauthd-[Daemon connectToExistingContext:callback:processId:userId:auditSessionId:auditToken:cApiOrigin:checkEntitlementBlock:invalidationBlock:connectionHash:reply:] 0, 5905, 501, 0, 0, 6e355c0 on <private>
standard12:13:34.437690+0100coreauthd-[ContextManager loadModule:error:] 1 on <private>
standard12:13:34.438297+0100<OURAPP>-[LAContext initWithExternalizedContext:userSession:] 0, (null), <LAClient: 0x28357f420> on <private>
standard12:13:34.438374+0100<OURAPP>-[LAClient externalizedContext] on <private>
standard12:13:34.438457+0100<OURAPP>-[LAClient externalizedContextWithReply:] on <private>
standard12:13:34.438580+0100coreauthd-[ContextProxy externalizedContextWithReply:] on <private>
standard12:13:34.438631+0100coreauthd-[ContextPluginACM externalizedContextWithReply:] on <private>
standard12:13:34.438791+0100coreauthd-[ContextProxy externalizedContextWithReply:]_block_invoke -> 63171931, (null) on <private>
standard12:13:34.438889+0100<OURAPP>-[LAClient externalizedContextWithReply:]_block_invoke -> 63171931, (null) on <private>
standard12:13:34.444027+0100duetexpertd{"msg":"CLLocationManager", "event":"activity", "_cmd":"location", "self":"0x102d2d590"}
standard12:13:34.446501+0100locationd{"msg":"client getting effective client name", "bundleId":"", "bundlePath":"\/System\/Library\/PrivateFrameworks\/CoreParsec.framework"}
standard12:13:34.446783+0100kernelAppleKeyStore: operation failed (pid: 96 sel: 43 ret: e007c007 '-536363001')
standard12:13:34.447005+0100securityddecode genp,rowid=20311 failed (-25291): Error Domain=NSOSStatusErrorDomain Code=-25291 "aks_ref_key: e007c007 failed to 'decrypt' item (class 0, bag: 0)" UserInfo={NSDescription=aks_ref_key: e007c007 failed to 'decrypt' item (class 0, bag: 0)}
standard12:13:34.447068+0100securityd<OURAPP>[5905]/1#6 LF=0 copy_matching Error Domain=NSOSStatusErrorDomain Code=-25291 "aks_ref_key: e007c007 failed to 'decrypt' item (class 0, bag: 0)" UserInfo={NSDescription=aks_ref_key: e007c007 failed to 'decrypt' item (class 0, bag: 0)}
standard12:13:34.447149+0100<OURAPP>-[LAContext dealloc] , <LAClient: 0x28357f420> on <private>
standard12:13:34.449052+0100coreauthdConnection invalidated: <NSXPCConnection: 0x106e355c0> connection on mach service named com.apple.CoreAuthentication.daemon from pid 5905 hash: 6e355c0
standard12:13:34.449284+0100coreauthd-[ContextProxy dealloc] on <private>


Logs shouldn't contain personal data, right? This is just a contiuous cutout of logs around the issue. I didn't modify the logs itself as I didn't see the need because no personal data is visible as far as I can tell.


@gc or @eskimo, can you help us here?

An answer to these logs would be so helpful or even a hack. I'm a little worried about the few (what's right, it's a really small amount ±6 users out of ±300k) users and what this might lead to in the future.

Since this thread was last active I’ve handled a number of DTS TSIs about this errSecNotAvailable error. So far all the errors have been associated with a log entry like this:

type: default
time: 2021-03-02 14:30:55.255111 +0300
process: kernel
category: <Missing Description>
message: AppleSEPKeyStore:10708:108: operation failed (sel: 43 ret: e007c007)

AppleKeyStore (AKS) is a kernel component that wrangles keys, including keys protected by the Secure Enclave. That e007c007 error translates to ‘bad device key’, which indicates that the device has got itself into a state where AKS is unable to unwrap a key.

It’s not clear how this happened. Apple has various bugs on file about this (r. 75428695) but the very rare occurrence of it makes it hard to debug. If you see this happen on a device you control, please trigger a sysdiagnose log as soon as possible and file a bug with that.

From a developer perspective there’s nothing you can do to recover the keychain item. For example, restarting the device won’t help. Based on my conversations with other developers, it seems that you can clear this error by deleting and re-creating the keychain item whose access is failing in this way. In a lot of cases that simply involves re-running the enrolment process in your app.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"