zeroclaw-labs/zeroclaw · error

Credential ID too long ({} bytes, max {MAX_CREDENTIAL_ID_LEN

Error message

Credential ID too long ({} bytes, max {MAX_CREDENTIAL_ID_LEN})

What it means

finish_registration base64url-decodes the credential ID and enforces the WebAuthn spec limit: at most MAX_CREDENTIAL_ID_LEN (1024) bytes. Longer IDs indicate a non-compliant or malicious authenticator, or a client that mangled the field, and are rejected.

Source

Thrown at crates/zeroclaw-runtime/src/security/webauthn.rs:312

        );

        // 2. Parse attestation object to extract public key and auth data
        let attestation_bytes = URL_SAFE_NO_PAD
            .decode(&response.attestation_object)
            .context("Invalid base64url in attestation_object")?;

        // For "none" attestation, we extract the authData which contains the
        // credential public key. The attestation object is CBOR-encoded but
        // for our minimal implementation we accept a simplified JSON format
        // from our enrollment UI, or parse the raw CBOR authData.
        let (public_key_bytes, sign_count) =
            extract_public_key_from_attestation(&attestation_bytes)?;

        // 3. Validate credential ID length
        let cred_id_bytes = URL_SAFE_NO_PAD
            .decode(&response.id)
            .context("Invalid base64url in credential ID")?;
        anyhow::ensure!(
            cred_id_bytes.len() <= MAX_CREDENTIAL_ID_LEN,
            "Credential ID too long ({} bytes, max {MAX_CREDENTIAL_ID_LEN})",
            cred_id_bytes.len()
        );

        let now = chrono::Utc::now().to_rfc3339();
        let label = response
            .label
            .clone()
            .unwrap_or_else(|| "Hardware Key".into());

        let credential = WebAuthnCredential {
            credential_id: response.id.clone(),
            public_key: URL_SAFE_NO_PAD.encode(&public_key_bytes),
            sign_count,
            label,
            registered_at: now,
            algorithm: COSE_ALG_ES256,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Reproduce with a mainstream browser and built-in passkey support to confirm the authenticator is at fault
  2. Check the client sends response.id as the base64url encoding of the raw credential ID and nothing else
  3. Treat authenticators that exceed 1024 bytes as non-compliant and reject them — do not raise the limit
Defensive patterns

Strategy: validation

Validate before calling

// client-side sanity: the ID must be short base64url, not raw bytes
if (resp.id.length > 1400 || !/^[A-Za-z0-9_-]+$/.test(resp.id)) {
  throw new Error('credential id is not valid base64url or exceeds the 1024-byte limit');
}

Try / catch

catch and map to HTTP 400; treat repeated oversized IDs from the same authenticator model as a compatibility signal and surface it in QA reports

Prevention

When it happens

Trigger: A non-compliant security key or platform authenticator emitting an oversized ID; a test client sending the raw bytes or the wrong field instead of base64url of the ID; concatenated/modified ID values produced by a client-side wrapper.

Common situations: Exotic or buggy authenticators during QA; custom client implementations serializing the wrong property; fuzzing payloads against the register endpoint.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/6c598abfd7895959. Report an issue: GitHub.