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
- Reproduce with a mainstream browser and built-in passkey support to confirm the authenticator is at fault
- Check the client sends response.id as the base64url encoding of the raw credential ID and nothing else
- 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
- Test the register flow with mainstream browsers/platform authenticators before shipping
- Do not hand-construct credential IDs in tests; generate realistic ones under 1024 bytes
- Never raise the limit — it is a WebAuthn spec bound, not a tunable
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
- Unable to extract public key from attestation object ({} byt
- Expected type 'webauthn.create', got '{cd_type}'
- Challenge mismatch in registration response
- Origin mismatch: expected '{}', got '{cd_origin}'
- Credential ID not in allowed list
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/6c598abfd7895959.
Report an issue: GitHub.