odoo/odoo · error · InvalidRegistrationResponse
Unsupported credential public key alg "{decoded_credential_p
Error message
Unsupported credential public key alg "{decoded_credential_public_key.alg}", expected one of: {supported_pub_key_algs} What it means
Raised when the decoded COSE credential public key's algorithm (alg) is not in supported_pub_key_algs (default ES256=-7, RS256=-257, and in newer versions Ed25519=-8). The RP only stores keys it can verify later, so unsupported algorithms are rejected at registration time.
Source
Thrown at addons/auth_passkey/_vendor/webauthn/registration/verify_registration_response.py:190
raise InvalidRegistrationResponse("Authenticator did not provide attested credential data")
attested_credential_data = auth_data.attested_credential_data
if not attested_credential_data.credential_id:
raise InvalidRegistrationResponse("Authenticator did not provide a credential ID")
if not attested_credential_data.credential_public_key:
raise InvalidRegistrationResponse("Authenticator did not provide a credential public key")
if not attested_credential_data.aaguid:
raise InvalidRegistrationResponse("Authenticator did not provide an AAGUID")
decoded_credential_public_key = decode_credential_public_key(
attested_credential_data.credential_public_key
)
if decoded_credential_public_key.alg not in supported_pub_key_algs:
raise InvalidRegistrationResponse(
f'Unsupported credential public key alg "{decoded_credential_public_key.alg}", expected one of: {supported_pub_key_algs}'
)
# Prepare a list of possible root certificates for certificate chain validation
pem_root_certs_bytes: List[bytes] = []
if pem_root_certs_bytes_by_fmt:
custom_certs = pem_root_certs_bytes_by_fmt.get(attestation_object.fmt)
if custom_certs:
# Load any provided custom root certs
pem_root_certs_bytes.extend(custom_certs)
if attestation_object.fmt == AttestationFormat.NONE:
# A "none" attestation should not contain _anything_ in its attestation statement
any_att_stmt_fields_set = any(
[field is not None for field in asdict(attestation_object.att_stmt).values()]
)
if any_att_stmt_fields_set:View on GitHub (pinned to 1e661df964)
Solutions
- Align both sides: advertise the same algorithms in pubKeyCredCredParams when generating registration options and in supported_pub_key_algs when verifying
- If your users have RSA-only authenticators, extend supported_pub_key_algs with RS256 (-257)
- Never add RS1 (-35, SHA-1) unless strictly required for legacy devices; prefer Ed25519 (-8) or ES256 (-7)
Example fix
# before
verified = verify_registration_response(
credential=credential, expected_challenge=challenge,
expected_origin=origin, expected_rp_id=rp_id,
require_user_verification=True,
)
# after - keep options and verification in sync
from py_webauthn import COSEAlgorithmIdentifier
algs = [COSEAlgorithmIdentifier.ECDSASHA256, COSEAlgorithmIdentifier.RSASSAPKCS1v1_5SHA256]
options = generate_registration_options(
rp_id=rp_id, rp_name=name, user_id=uid,
pub_key_cred_params=[{'type': 'public-key', 'alg': a.value} for a in algs],
)
verified = verify_registration_response(
credential=credential, expected_challenge=challenge,
expected_origin=origin, expected_rp_id=rp_id,
require_user_verification=True,
supported_pub_key_algs=algs,
)
Defensive patterns
Strategy: validation
Validate before calling
from py_webauthn import COSEAlgorithmIdentifier SUPPORTED = [COSEAlgorithmIdentifier.ECDSASHA256, COSEAlgorithmIdentifier.RSASSAPKCS1v1_5SHA256] # Use the same list for generate_registration_options(pub_key_cred_params=...) and # verify_registration_response(supported_pub_key_algs=SUPPORTED).
Type guard
const SUPPORTED_ALGS = new Set([-7, -257]);
// after decoding the COSE key client-side (or in a shared lib):
function isSupportedAlg(alg: unknown): alg is number {
return typeof alg === 'number' && SUPPORTED_ALGS.has(alg);
} Try / catch
try:
verify_registration_response(..., supported_pub_key_algs=SUPPORTED)
except InvalidRegistrationResponse as e:
if 'Unsupported credential public key alg' in str(e):
return user_error('Your device uses a key type this service does not support')
raise Prevention
- Keep one shared constant for algorithms and use it in both options generation and verification
- Advertise at least ES256 (-7) and RS256 (-257) so virtually all devices can enroll
- Add a regression test that enrolls with each advertised alg
When it happens
Trigger: A credential created with an algorithm the RP did not list in publicKey.parameters ('alg') in the creation options, e.g. ES384, RS1 (SHA-1 RSA), or PS256; a custom supported_pub_key_algs argument that omits the algorithm the browser chose.
Common situations: Mistmatch between the algorithms advertised in the registration options (publicKey.pubKeyCredParams) and the supported_pub_key_algs passed to verification; older Windows Hello or Android devices emitting RS1; explicitly restricting to ES256 while the user's device only supports RSA.
Related errors
- Authenticator did not provide a credential public key
- id and raw_id were not equivalent
- Unexpected credential type "{credential.type}", expected "pu
- Unexpected client data type "{client_data.type}", expected "
- User verification is required but user was not verified duri
AI-assisted analysis of odoo/odoo@1e661df964 (2026-08-15).
Data as JSON: /api/errors/43eea84c4068dd5d.
Report an issue: GitHub.