{"record":{"id":"ca7f60fbbfc522c4","repo":"quarkusio/quarkus","slug":"invalid-cose-algorithm-cosealgorithm","errorCode":null,"errorMessage":"Invalid cose algorithm: ${coseAlgorithm}","messagePattern":"Invalid cose algorithm: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnCredentialRecord.java","lineNumber":137,"sourceCode":"        COSEKey coseKey;\n        try {\n            switch (coseAlgorithm.getKeyType()) {\n                case EC2:\n                    coseKey = EC2COSEKey.create((ECPublicKey) KeyFactory.getInstance(\"EC\").generatePublic(x509EncodedKeySpec),\n                            coseAlgorithm);\n                    break;\n                case OKP:\n                    coseKey = EdDSACOSEKey\n                            .create((EdECPublicKey) KeyFactory.getInstance(\"EdDSA\").generatePublic(x509EncodedKeySpec),\n                                    coseAlgorithm);\n                    break;\n                case RSA:\n                    coseKey = RSACOSEKey\n                            .create((RSAPublicKey) KeyFactory.getInstance(\"RSA\").generatePublic(x509EncodedKeySpec),\n                                    coseAlgorithm);\n                    break;\n                default:\n                    throw new IllegalArgumentException(\"Invalid cose algorithm: \" + coseAlgorithm);\n            }\n        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {\n            throw new IllegalArgumentException(\"Invalid public key\", e);\n        }\n        byte[] credentialId = base64UrlDecode(persistedData.credentialId());\n        AAGUID aaguid = new AAGUID(persistedData.aaguid());\n        AttestedCredentialData attestedCredentialData = new AttestedCredentialData(aaguid, credentialId, coseKey);\n\n        return new WebAuthnCredentialRecord(persistedData.username(), counter, attestedCredentialData);\n    }\n\n    /**\n     * Record holding all the required persistent fields for logging back someone over WebAuthn.\n     */\n    public record RequiredPersistedData(\n            /**\n             * The user name. A single user name may be associated with multiple WebAuthn credentials.\n             */","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security-webauthn/runtime/src/main/java/io/quarkus/security/webauthn/WebAuthnCredentialRecord.java#L119-L155","documentation":"When reassembling a WebAuthn credential from persisted data, the stored COSE algorithm identifier determines the key type branch (EC2, OKP, RSA). If the resolved COSEAlgorithmIdentifier's key type is none of these, fromRequiredPersistedData throws IllegalArgumentException and WebAuthn login/re-authentication for that credential fails.","triggerScenarios":"Calling WebAuthnCredentialRecord.fromRequiredPersistedData with a RequiredPersistedData whose publicKeyAlgorithm maps to an unsupported COSE key type (anything other than EC2/OKP/RSA), e.g. a corrupted or hand-crafted algorithm number.","commonSituations":"Persisted data written by a different library version or manually edited rows; database column holding a wrong/garbage algorithm integer; credentials registered with exotic algorithms not supported by webauthn4j's supported set here.","solutions":["Check the persisted publicKeyAlgorithm value in your database and restore it to the original value captured at registration (e.g. -7 ES256, -257 RS256, -8 EdDSA).","Re-register the affected credential so fresh, correct RequiredPersistedData is stored.","Validate persisted data integrity at write time; never hand-edit these rows.","Ensure the Quarkus WebAuthn extension and webauthn4j versions match across environments sharing the database."],"exampleFix":"// before (persisted)\npublicKeyAlgorithm = 999\n\n// after\npublicKeyAlgorithm = -7 // ES256, as returned at registration\n// or re-register the credential","handlingStrategy":"validation","validationCode":"int alg = persistedData.publicKeyAlgorithm();\nif (alg != -7 && alg != -257 && alg != -8 && alg != -36 && alg != -47 && alg != -48) {\n    throw new IllegalStateException(\"Unsupported persisted COSE algorithm: \" + alg);\n}","typeGuard":null,"tryCatchPattern":"try {\n    record = WebAuthnCredentialRecord.fromRequiredPersistedData(persistedData);\n} catch (IllegalArgumentException e) {\n    // mark credential unusable; force re-registration\n    log.error(\"Unusable persisted WebAuthn credential, forcing re-registration\", e);\n    credentialRepository.delete(persistedData.credentialId());\n}","preventionTips":["Persist RequiredPersistedData exactly as produced by getRequiredPersistedData().","Never hand-edit algorithm or key columns in the DB.","Re-register credentials when the extension/webauthn4j version changes behavior."],"tags":["quarkus","webauthn","runtime","cose"],"backgroundTag":"invalid-public-key","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}