Skip to content

iOS: Passkey creation randomly fails with error 1004 after app reinstall — "Unable to verify webcredentials association" #96

@vaizakhter

Description

@vaizakhter

Description

Passkey creation via Passkey.create() / Passkey.createPlatformKey() randomly fails with error 1004 (RequestFailed) after app delete + reinstall. The passkey system popup never appears. This does not happen on every reinstall — it occurs roughly 5% of the time, making it difficult to reproduce consistently.

First-time installs always work. The issue only surfaces after delete + reinstall, and once it occurs, it persists indefinitely — retrying after minutes or even hours does not resolve it.

Error

The JS error received:

{ "error": "RequestFailed", "message": "The request failed. No Credentials were returned." }

After patching handleErrorCode in Passkey.swift to extract NSLocalizedFailureReason, the actual cause is revealed:

Unable to verify webcredentials association of <TEAM_ID>.<BUNDLE_ID>
with domain <your-domain>. Please try again in a few seconds.

This diagnostic info is currently discarded by the library — the JS side only sees the generic "No Credentials were returned" message.

AASA Configuration

The AASA file is correctly configured and verified on Apple's CDN:

$ curl -s "https://app-site-association.cdn-apple.com/a/v1/<your-domain>"
{
  "webcredentials": {
    "apps": ["<TEAM_ID>.<BUNDLE_ID>"]
  }
}

We also confirmed at runtime that the device can reach Apple's CDN — a fetch() to the same URL from within the app returns HTTP 200 with correct JSON. The domain association data is available, but iOS fails to verify it.

Steps to Reproduce

  1. Install app → call Passkey.create() → ✅ works
  2. Delete the app
  3. Reinstall the app
  4. Call Passkey.create() → ❌ ~5% chance of error 1004
  5. If it fails, retry after minutes/hours → ❌ still fails (stuck state)
  6. Reset Network Settings on device → ✅ always fixes it

Note: This is intermittent and may take several delete + reinstall cycles to trigger.

Environment

Dependency Version
react-native-passkey 3.3.2
React Native 0.76.x
iOS 17.x / 18.x
Devices iPhone 14 Pro Max, iPhone 15 Pro (real devices, not simulator)

Investigation

This is a known Apple platform issue where iOS randomly fails to re-verify the AASA domain association after app reinstall. It affects ~5% of installs according to reports on Apple Developer Forums. Once the verification fails, iOS caches the failure and does not retry — the device enters a stuck state.

What fixes it at the device level

Action Result
Retry from app (minutes/hours) ❌ Does not fix
Device reboot ⚠️ Works on some devices, not all
Multiple uninstall/reinstall cycles ⚠️ Eventually succeeds
Reset Network Settings ✅ Always works
?mode=developer in associated domains entitlements ✅ Always works (debug builds only)

Request

1. Expose NSLocalizedFailureReason in error messages

Currently handleErrorCode in Passkey.swift discards the actual failure reason:

// Current — generic message, real cause hidden
case 1004:
  return RNPasskeyError(type: .requestFailed, message: error.localizedDescription)

Proposed change:

case 1004:
  let nsError = error as NSError
  var parts: [String] = [error.localizedDescription]
  if let reason = nsError.localizedFailureReason {
    parts.append("reason: \(reason)")
  }
  return RNPasskeyError(type: .requestFailed, message: parts.joined(separator: " | "))

This would allow JS-side code to:

  • Detect retryable errors: error.message.includes('try again')
  • Detect domain issues: error.message.includes('Unable to verify')
  • Show users appropriate guidance instead of a generic failure

2. Has anyone else encountered this?

Looking for any known workarounds at the library or native level. Happy to submit a PR for the error reporting enhancement.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions