Error message
Provided key is too short
Also printed as
- DomainException: Provided key is too short
Thrown by both `JWT::encode` and `JWT::decode`. php-jwt 6.x and earlier accepted short keys, so the error typically appears right after upgrading to 7.x.
firebase/php-jwt 7.x (PHP) — DomainException from JWT::encode / JWT::decode
What it means
php-jwt 7 checks key sizes before signing or verifying: an HMAC secret must have at least as many bits as the hash (32 bytes for HS256, 48 for HS384, 64 for HS512), an RSA key at least 2048 bits, and an EC key at least the size its algorithm implies. A shorter key is rejected because tokens protected by it can be forged — short HMAC secrets fall to offline brute force, 1024-bit RSA is below current minimums.
Why it happens
A short, human-made HMAC secret
commonValues like `secret`, `change-me-please` or an app name are far below 32 bytes and are often guessable as well.
Upgrading php-jwt from 6.x to 7.x
commonVersion 7 added the minimum key-size checks. Code and secrets that worked for years fail on the first request after `composer update`.
A 1024-bit RSA key
occasionalOld keys generated with 1024 bits (or copied from examples) are rejected for RS256/RS384/RS512.
How to fix it
- 1.
Generate a new random secret
Use `random_bytes` or `openssl rand` and keep the secret in a secret store. Rotating it invalidates existing tokens, so plan a short overlap if needed.
bash # HS256 needs >= 32 bytes, HS512 >= 64; generate and store as base64 php -r 'echo base64_encode(random_bytes(64)), PHP_EOL;' - 2.
Store it base64-encoded, use the decoded bytes
Validate the length once at startup so a weak secret fails deployment instead of the first request.
php $secret = base64_decode(getenv('JWT_SECRET_B64'), true); if ($secret === false || strlen($secret) < 32) { throw new RuntimeException('JWT_SECRET_B64 must decode to at least 32 bytes'); } $token = JWT::encode($claims, $secret, 'HS256'); $decoded = JWT::decode($token, new Key($secret, 'HS256')); - 3.
Replace small RSA keys
Generate a 2048-bit or larger RSA key — or switch to ES256 with a P-256 key — and publish the new public key before signing with it.
bash openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rs256-private.pem