{"record":{"id":"304d176ec88e9f32","repo":"lcobucci/jwt","slug":"the-length-of-the-provided-key-is-different-than","errorCode":null,"errorMessage":"The length of the provided key is different than {expectedLength} bits, {actualLength} bits provided","messagePattern":"The length of the provided key is different than (.+?) bits, (.+?) bits provided","errorType":"exception","errorClass":"Lcobucci\\JWT\\Signer\\InvalidKeyProvided","httpStatus":null,"severity":"error","filePath":"src/Signer/Ecdsa.php","lineNumber":48,"sourceCode":"            $payload,\n            $key,\n        );\n    }\n\n    /** {@inheritDoc} */\n    final protected function guardAgainstIncompatibleKey(int $type, int $lengthInBits): void\n    {\n        if ($type !== OPENSSL_KEYTYPE_EC) {\n            throw InvalidKeyProvided::incompatibleKeyType(\n                self::KEY_TYPE_MAP[OPENSSL_KEYTYPE_EC],\n                self::KEY_TYPE_MAP[$type] ?? 'unknown',\n            );\n        }\n\n        $expectedKeyLength = $this->expectedKeyLength();\n\n        if ($lengthInBits !== $expectedKeyLength) {\n            throw InvalidKeyProvided::incompatibleKeyLength($expectedKeyLength, $lengthInBits);\n        }\n    }\n\n    /** {@inheritDoc} */\n    final protected function guardAgainstIncompatibleCurve(?string $curveName): void\n    {\n        $expectedCurve = $this->expectedCurve();\n\n        if ($curveName !== $expectedCurve) {\n            throw InvalidKeyProvided::incompatibleKeyCurve($expectedCurve, $curveName ?? 'unknown');\n        }\n    }\n\n    /**\n     * @internal\n     *\n     * @return positive-int\n     */","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Signer/Ecdsa.php#L30-L66","documentation":"After confirming the key is an EC key, Ecdsa's guardAgainstIncompatibleKey compares the key's bit length (details['bits']) with the length required by the concrete signer via expectedKeyLength() (256 for ES256, 384 for ES384, 512 for ES512). A mismatch throws InvalidKeyProvided::incompatibleKeyLength, because an ECDSA signature scheme is bound to a specific curve/key size.","triggerScenarios":"Using e.g. an ES384 signer with a P-256 (256-bit) key, or an ES256 signer with a P-521 key — sign() or verify() resolves the key details and calls guardAgainstIncompatibleKey($type, $bits).","commonSituations":"Generating an EC key without matching the curve to the algorithm (openssl ecparam default curve differs from the signer's expectation); switching the JWT algorithm in config from ES256 to ES384 without regenerating keys; hardcoding one key pair for multiple signers.","solutions":["Match the curve to the algorithm: prime256v1 for ES256 (256 bits), secp384r1 for ES384 (384 bits), secp521r1 for ES512 (521 bits — note the signer's expected length semantics).","Check the actual key size: openssl_pkey_get_details(openssl_pkey_get_private($pem))['bits'] and compare with the signer's expectedKeyLength().","Regenerate the key pair with the correct curve: openssl ecparam -name secp384r1 -genkey -noout -out key.pem.","Or instantiate the signer matching the key you already have (Es256 for a 256-bit key, etc.) instead of changing keys."],"exampleFix":"// before\n$signer = new Es384();\n$key = new Key(file_get_contents('p256-key.pem')); // 256 bits -> incompatibleKeyLength\n\n// after\nshell_exec('openssl ecparam -name secp384r1 -genkey -noout -out p384-key.pem');\n$signer = new Es384();\n$key = new Key(file_get_contents('p384-key.pem')); // 384 bits","handlingStrategy":"validation","validationCode":"$details = openssl_pkey_get_details(openssl_pkey_get_private($pem));\nif (($details['bits'] ?? 0) !== $signer::expectedBits()) { // e.g. 256 for Es256\n    throw new InvalidArgumentException(sprintf('Key is %d bits; signer requires %d bits', $details['bits'] ?? 0, $signer::expectedBits()));\n}","typeGuard":"function keyMatchesEcdsaBits(string $pem, int $expectedBits): bool\n{\n    $key = openssl_pkey_get_private($pem);\n    $details = $key === false ? null : openssl_pkey_get_details($key);\n    return ($details['bits'] ?? -1) === $expectedBits;\n}","tryCatchPattern":"try {\n    $signature = $signer->sign($payload, $key);\n} catch (InvalidKeyProvided $e) {\n    throw new ConfigurationException('ECDSA key length mismatch: ' . $e->getMessage(), previous: $e);\n}","preventionTips":["Map algorithm to curve explicitly (ES256->prime256v1, ES384->secp384r1, ES512->secp521r1) and document it next to key generation commands.","Never share one EC key pair among signers of different curve sizes.","Check ['bits'] from openssl_pkey_get_details immediately after loading or rotating keys.","Add a CI check that validates every configured signing key's type/curve/bits against its signer."],"tags":["ecdsa","key-length","curve","signing"],"backgroundTag":"invalid-key-length","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}