LayerZeroFault
passkey recovery

Fix: WebAuthn Resident Key (Discoverable Credential) Overflow in Hardware Authenticators

VV

Written by

Fact-Checked on September 11, 2026

Verified Expert

Fix: WebAuthn Resident Key (Discoverable Credential) Overflow in Hardware Authenticators

When deploying or creating ERC-4337 Smart Accounts powered by WebAuthn passkeys (such as Coinbase Smart Wallet, ZeroDev Kernel, or Safe), hardware security keys like YubiKey (5 Series, 5Ci, Bio), Google Titan, or Feitian ePass provide the highest tier of private key security.

However, power users who secure multiple dApps, exchanges, and enterprise logins frequently encounter an abrupt failure during the passkey enrollment ceremony:

DOMException: The operation failed for an unknown reason.
[Status: OperationError]

or in Chromium developer consoles:

NotAllowedError: The operation either timed out or was not allowed. 
[CTAP2 error: 0x3A - CTAP2_ERR_KEY_STORE_FULL]

If your passkey issues are instead related to Windows Hello biometric lockout, see our dedicated guide on Fixing Windows Hello TPM Passkey Enclave Lock.


Technical Cause: FIDO2 Discoverable Credential NVRAM Constraints

Unlike software passkeys (iCloud Keychain, Google Password Manager, 1Password) which synchronize credentials to virtually limitless cloud databases, hardware security keys utilize isolated cryptographic microcontrollers with dedicated Non-Volatile RAM (NVRAM).

In the FIDO2 / CTAP2.1 specification, credentials fall into two categories:

  1. Non-Resident Keys (Server-Side Credentials): The private key is encrypted inside the credentialId using a master secret on the key. The key stores zero bytes on the device, allowing unlimited credentials.
  2. Resident Keys (Discoverable Credentials): The private key, username, and Relying Party ID are written directly into physical hardware flash memory so that the user can sign in without typing their username first.

Placeholder: Hardware Security Key Flash Memory Partitioning Diagram Showing NVRAM Limits

Hardware Storage Capacities

Hardware DeviceFirmware VersionResident Key Slot Limit
YubiKey 5 Series$< 5.7.0$25 passkeys
YubiKey 5 Series$\ge 5.7.0$100 passkeys
YubiKey BioAll25 passkeys
Google Titan Key2023+ Edition250 passkeys
Feitian ePass K9/K40Standard32 passkeys

Because Account Abstraction smart wallets require user-less authentication (the user taps their hardware key to retrieve their smart contract account), dApps specify:

{
  "authenticatorSelection": {
    "residentKey": "required",
    "requireResidentKey": true,
    "userVerification": "required"
  }
}

Once you reach the 25th credential on older YubiKey firmware, any subsequent navigator.credentials.create() request returns CTAP2_ERR_KEY_STORE_FULL (0x3A).


Step-by-Step Diagnostic & Key Management

Method 1: Inspect & Delete Passkeys via YubiKey Manager (ykman)

The fastest way to diagnose storage saturation is via the open-source Yubico CLI:

# 1. Install ykman (macOS: brew install ykman | Windows: winget install Yubico.YubiKeyManager)
ykman --version

# 2. List all resident FIDO2 credentials (requires FIDO2 PIN)
ykman fido credentials list

Sample Output:

Enter your FIDO2 PIN: ****
Credential ID                                     RP ID               User name
------------------------------------------------  ------------------  ----------------------
3f4a1c2e8b...                                     coinbase.com        0x9B2...7A1
a7c8d9e0f1...                                     layerzerofault.site victor.vance
... (25 total entries)

To free up slots for your Web3 smart wallet:

# Delete a specific obsolete credential using its Credential ID
ykman fido credentials delete <CREDENTIAL_ID>

Placeholder: Terminal Interface Showing ykman FIDO2 Credential Deletion Flow

Method 2: Manage Passkeys via Windows 11 Settings

Windows 11 includes a native passkey management dashboard for external security keys:

  1. Open Windows Settings $\to$ Accounts $\to$ Passkeys.
  2. Scroll to Security Key Settings and click Manage.
  3. Insert your hardware key into the USB port and enter your Security Key PIN.
  4. Review the list of stored credentials and remove old, deprecated dApp test credentials.

Developer Defense: Graceful Fallback Handling in Web3 dApps

When writing client-side WebAuthn onboarding code with @simplewebauthn/browser or Wagmi / Viem passkey connectors, never let OperationError or 0x3A fail silently.

Catch the error and prompt the user with clear hardware-capacity instructions:

// passkey-registration-guard.ts
import { startRegistration } from '@simplewebauthn/browser';
import type { PublicKeyCredentialCreationOptionsJSON } from '@simplewebauthn/types';

export async function registerPasskeyWithStorageCheck(
  options: PublicKeyCredentialCreationOptionsJSON
) {
  try {
    const credential = await startRegistration({ optionsJSON: options });
    return credential;
  } catch (error: any) {
    // Detect FIDO2 hardware storage overflow
    const errorMessage = error?.message || '';
    const isStorageFull =
      errorMessage.includes('OperationError') ||
      errorMessage.includes('0x3A') ||
      errorMessage.includes('KEY_STORE_FULL') ||
      (error.name === 'NotAllowedError' && errorMessage.includes('unknown reason'));

    if (isStorageFull) {
      throw new Error(
        'Hardware Security Key Full: Your device (YubiKey/Titan) has reached its maximum resident key limit (25–100 credentials). Please delete unused passkeys using YubiKey Manager or use a platform passkey (Windows Hello / Touch ID).'
      );
    }

    throw error;
  }
}

Placeholder: Frontend Modal Diagram Displaying Actionable Storage Full Toast to User


Best Practice Architecture: Use residentKey: "preferred"

If your smart contract architecture can accept an address or username during the initial lookup phase, change residentKey from "required" to "preferred":

// Config that allows non-resident fallback when hardware key is full
const options = {
  authenticatorSelection: {
    authenticatorAttachment: 'cross-platform',
    residentKey: 'preferred', // Allows non-resident key creation if storage is full!
    requireResidentKey: false,
    userVerification: 'preferred',
  },
};

This configuration permits the hardware key to fall back to generating a non-resident key wrapped inside the credentialId, completely bypassing physical NVRAM slot exhaustion.

Partner Spotlight: Gate.io

Trade Securely on Gate.io

Don't risk your assets on centralized silos or unverified endpoints. Trade securely on Gate.io with deep liquidity and institutional-grade security protocols.

Claim $100 Sign-up Bonus

Official Partner Referral Link

Related Inquiries

Why does navigator.credentials.create() fail with OperationError when using a hardware security key?

Hardware security keys such as YubiKey 5 Series have hardware NVRAM limits for FIDO2 Resident Keys (Discoverable Credentials) — typically 25 to 100 credentials. When smart accounts request residentKey: 'required' and the key's onboard memory is full, the device returns CTAP2 error 0x3A (CTAP2_ERR_KEY_STORE_FULL), which the browser surfaces as DOMException: OperationError or NotAllowedError.

How can I check how many passkeys are stored on my YubiKey?

Use the official YubiKey Manager CLI (ykman). Run 'ykman fido credentials list' in your terminal. It will prompt for your FIDO2 PIN and output all resident credentials grouped by Relying Party ID (rpId) along with remaining capacity.

How should Web3 dApps configure WebAuthn registration to avoid hardware memory limits?

In the PublicKeyCredentialCreationOptions payload, set authenticatorSelection.residentKey to 'preferred' rather than 'required' when discoverable credentials are not strictly necessary, or allow users to supply an existing credentialId for server-side lookup.