iOS Keychain randomly returning -25300

I am facing a strange issue in my app. My code saves a string password in the iOS keychain to be accessed later on. It works just fine most of the times and I am able to fetch the password back after reinstallation or device restart or both.

Problem: Sometimes which is actually rare and hard to reproduce, it does NOT return the password and instead it returns null and error status:-25300(errSecItemNotFound). Another thing is that this problem got prominent after iOS 9 update. Happening on iOS 9.1 too.


Code for setting:


NSMutableDictionary *query = [self _queryForService:service account:account]; 
[query setObject:password forKey:(__bridge id)kSecValueData]; 
status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

if (status != errSecSuccess && error != NULL) { 
*error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil]; } 
return (status == noErr);


Code for fetching:


CFTypeRef result = NULL; 
NSMutableDictionary *query = [self _queryForService:service account:account]; 
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 
status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);

if (status != errSecSuccess && error != NULL) { 
*error = [NSError errorWithDomain:kAppKeychainErrorDomain code:status userInfo:nil]; 
return nil; 
} 
return (__bridge_transfer NSData *)result;


Has anyone got any ideas why this is happening? Many thanks.

Post not yet marked as solved Up vote post of captalvins Down vote post of captalvins
25k views

Replies

Oh! Thanks... I have raised a bug with Apple. Let see how it goes! Will post the outcome here.

We also have users experiencing the same "random" -25300 errSecItemNotFound issue. I'm fairly confident that the keychain items are configured properly since they can be read back without issue the vast majority of the time and they are only set once on the first run of the app (and are never deleted by the application).


The problem does seem to resolve itself after a period of time (on the order of hours, according to affected users) which also seems to suggest the keychain item configuration is not the problem. Dumping the keychain when experiencing this issue shows none of the expected keychain entries.


We have only experienced this issue with iOS 9 devices, and approximately 3% of our users have experienced it at least once. It does seem like some users are much more likely to experience it based on the reporting we have.


Here is one device log that captures some information just prior to an app launch where the keychain access failed with an unexepected -25300.

https://gist.github.com/robmaceachern/0003ec44c37b01e72af9

This is the point the app launched https://gist.github.com/robmaceachern/0003ec44c37b01e72af9#file-device-log-25300-errsecitemnotfound-L496


There are a bunch of securityd errors in there that might shed a little light. These each were logged before the application launched:


securityd[83] <Error>: SecDbRecordChange db <SecDbConnection rw open> changed outside txn

securityd[83] <Error>: __SOSUpdateKeyInterest_block_invoke_2 Error getting ring interests (null)

securityd[83] <Error>: SecOCSPSingleResponseCalculateValidity OCSPSingleResponse: nextUpdate 0.73 days ago

securityd[83] <Error>: securityd_xpc_dictionary_handler cloudd[166] copy_matching Error Domain=NSOSStatusErrorDomain Code=-50 "query missing class name" UserInfo={NSDescription=query missing class name}

securityd[83] <Error>: secTaskDiagnoseEntitlements MISSING keychain entitlements: no stored taskRef found


Notes:

- The keychain items are accessed in application:didFinishLaunchingWithOptions:

- We use a library to do the actual keychain access: https://github.com/kishikawakatsumi/KeychainAccess

- The issue has occured on App Store distributed builds, enterprise distributed builds, and debug builds – but I don't know of any reliable reproduction steps

- Keychain sharing is not enabled

- The app makes frequent use of silent push notifications (content-available flag).

- Failures have been observed while the app is in UIApplicationStateInactive and UIApplicationStateBackground

- All keychain items use the kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly accessibility setting

- Having the user force close & re-open the app doesn't seem to resolve the problem.


Quinn: Do you have any suggestions on how to proceed on this? Any hunches on what to try when attempting to reproduce?

securityd[83] <Error>: secTaskDiagnoseEntitlements MISSING keychain entitlements: no stored taskRef found

My understanding is that these log messages are a recent addition to the system to help track down the very elusive -34018 error. Please file a bug with the info you have and then post the bug number here.

Some questions:

  • Is the user reporting this likely to be running Xcode?

  • What OS version were they running? If they’re running a 9.3 beta, it’s important to know which beta (that is, the build number).

  • Do they see any “simulated” crash logs on the device?

I’d like to know the answers to these questions myself, but it’s more important you put this info in your bug report.

Share and Enjoy

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

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

Thanks Quinn. I've filed bug number 24956853.


To answer your questions:


> Is the user reporting this likely to be running Xcode?


No, most reports of the issue are from non-developer users and don't have xcode or any other debugger attached to the app.


> What OS version were they running? If they’re running a 9.3 beta, it’s important to know which beta (that is, the build number).


We have seen this problem on iOS 9.2.1, 9.2.0, and 9.1.0. We haven't seen this problem on any version of iOS 8 (about ~7% of our active users are using iOS 8 devices). I don't believe any of our users are using 9.3 beta yet, and we haven't seen any reports of the issue from 9.3 devices.


> Do they see any “simulated” crash logs on the device?


We have seen some "simulated" crash logs that appear to be related to a background NSURLSession our application uses, however they don't seem to be restricted to devices experiencing the keychain problem. Similar simulated reports also appear for other processes: eg Flixter, Google Docs, Economist, etc). Gist is here: https://gist.github.com/robmaceachern/087e875a482a9dcd693e

Hi Quinn

As already reported above, I have also filed the bug a while ago for this. Bug no. is: 24270773.

Hi Captalvins,

Any luck with this bug or response from apple? My app is also getting this issue. We use keychain to store user credential and this issue causes a % of our user to consistently relogin. We also read from keychain on app startup in didFinishLaunchingWithOptions. We noticed disabling background app refresh seems to reduce # of occurrence or completely eliminate the issue. We haven't confirm if that solve the issue since we have no luck replicating it inhouse.

Edit: As a side note, our app does not have keychain sharing enable.

Thanks

Kun

anyone found a solution / workaround? Is moving the part where keychain access is needed to places other than didFinishLaunchingWithOptions (maybe in viewDidLoad) a workaround? This issue affects all iOS versions in my case and there is no solution found online. It's frustrating it happens randomly and it's unable to tell if the value really isn't in the keychain or it happens to be unreadable at that moment.

Even we are facing issue with this API. Keychain API returns -25300 eventhoug item is present.It is mostly happening with the appstore build and with the end users. Not sure when apple responds to this. It would be helpful if anyone suggests a reliable work around for this

After some more testing, found that disabling Background Modes helped and the issue was completely gone although I have no explanation for that. Would be very much appreciated if anyone can help explaining why the Background Modes capability setting affect reading the Keychain when the app opens.

Thanks.

The typical interaction point between background modes and the keychain is data protection, as surfaced by the

kSecAttrAccessible
attribute. For example, if you set the accessible attribute to
kSecAttrAccessibleWhenUnlocked
and then run in the background due to background fetch, it’s likely you’ll run into a situation where the keychain item isn’t accessible because the device is locked at the time you receive background fetch time.

Share and Enjoy

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

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

Not sure if this helps, but we also use silent push notifications for CallKit functionality (with content-available). We see nearly this exact same issue - here's how ours typically happens, while it is very very rarely reproduced.


1. Device receives a silent push (incoming video call for us).

2. App checks keychain for a user session - sees nil and returns

3. Upon opening app the next time (possibly still active in the background), the value we're looking for in Keychain is nil - user appears to be logged out and is presented with a login screen


Note: In our case, after item #3, if we kill the app and reopen it, everything is back to normal (Keychain returns a value for our user session)


My guess is that somehow Keychain is locked for reads during that entire app session.


We're also looking for a workaround. We've thought about using UserDefaults as a backup solution. Does anyone have anything to add?

What are you setting the

kSecAttrAccessible
attribute to?

Share and Enjoy

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

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

We've experienced this issue with Keychain on multiple projects now, even with `
kSecAttrAccessibleAlways`, so we've been forced to use UserDefaults or basic file system storage.


The original bug I filed (24956853) in 2016 was marked as a dupe, with the main issue closed as well, but this is definitely not fixed. There is something bad happening with keychain when background modes and/or silent push notifications are used on iOS.


https://forums.developer.apple.com/message/325932?et=watches.email.thread#325932

kSecAttrAccessible is set to

kSecAttrAccessibleAlwaysThisDeviceOnly


I've also added an SO post here with much more information

The original bug I filed (24956853) in 2016 was marked as a dupe, with the main issue closed as well, but this is definitely not fixed.

Your bug (r. 24956853) was closed as a dup of the infamous -34018 bug (r. 18766047) which was actually fixed. It seems likely that this is a different issue. I recommend that you file a new bug about this.

The hard part of this is providing enough information in the bug to be actionable. One option is to add code to your app that posts a local notification when it notices the problem. The user can then trigger a sysdiagnose log, which should be included with the bug report.

This probably isn’t something you should inflict on normal users, but it might be worthwhile including in versions you ship to beta users.

If you do file a bug, please post your bug number, just for the record.

Share and Enjoy

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

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