jwtk/jjwt · error · InvalidKeyException

SecretKey byte array cannot be null.

Error message

SecretKey byte array cannot be null.

What it means

Keys.hmacShaKeyFor throws InvalidKeyException when the byte array passed for building an HMAC-SHA SecretKey is null. A null key material cannot produce a usable signing key, so the library fails immediately before any length checks.

Source

Thrown at api/src/main/java/io/jsonwebtoken/security/Keys.java:62

    }

    //prevent instantiation
    private Keys() {
    }

    /**
     * Creates a new SecretKey instance for use with HMAC-SHA algorithms based on the specified key byte array.
     *
     * @param bytes the key byte array
     * @return a new SecretKey instance for use with HMAC-SHA algorithms based on the specified key byte array.
     * @throws WeakKeyException if the key byte array length is less than 256 bits (32 bytes) as mandated by the
     *                          <a href="https://tools.ietf.org/html/rfc7518#section-3.2">JWT JWA Specification
     *                          (RFC 7518, Section 3.2)</a>
     */
    public static SecretKey hmacShaKeyFor(byte[] bytes) throws WeakKeyException {

        if (bytes == null) {
            throw new InvalidKeyException("SecretKey byte array cannot be null.");
        }

        int bitLength = bytes.length * 8;

        //Purposefully ordered higher to lower to ensure the strongest key possible can be generated.
        if (bitLength >= 512) {
            return new SecretKeySpec(bytes, "HmacSHA512");
        } else if (bitLength >= 384) {
            return new SecretKeySpec(bytes, "HmacSHA384");
        } else if (bitLength >= 256) {
            return new SecretKeySpec(bytes, "HmacSHA256");
        }

        String msg = "The specified key byte array is " + bitLength + " bits which " +
                "is not secure enough for any JWT HMAC-SHA algorithm.  The JWT " +
                "JWA Specification (RFC 7518, Section 3.2) states that keys used with HMAC-SHA algorithms MUST have a " +
                "size >= 256 bits (the key size must be greater than or equal to the hash " +
                "output size).  Consider using the Jwts.SIG.HS256.key() builder (or HS384.key() " +

View on GitHub (pinned to fb71496164)

Solutions

  1. Ensure the secret bytes are non-null before calling: load and validate the env/config value
  2. Fail fast at startup with a clear message if the secret is absent
  3. Decode the secret (e.g. Base64) and assert it is non-empty prior to key construction

Example fix

// before
SecretKey key = Keys.hmacShaKeyFor(secretBytes); // NPE-ish InvalidKeyException if null
// after
if (secretBytes == null || secretBytes.length == 0) throw new IllegalStateException("JWT secret not configured");
SecretKey key = Keys.hmacShaKeyFor(secretBytes);
Defensive patterns

Strategy: validation

Validate before calling

if (secretBytes == null || secretBytes.length == 0) {
    throw new IllegalStateException("JWT secret not configured (env JWT_SECRET missing or empty)");
}

Try / catch

try {
    key = Keys.hmacShaKeyFor(secretBytes);
} catch (InvalidKeyException e) {
    throw new IllegalStateException("Invalid JWT secret configuration", e);
}

Prevention

When it happens

Trigger: Calling Keys.hmacShaKeyFor(null), typically when a secret was never loaded — e.g. an environment variable or config property is missing so the byte array variable is null.

Common situations: Missing JWT_SECRET env var in deployment, config loader returning null silently, or decoding a Base64 secret that was empty/absent.

Related errors


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/238d1f0c7ebfb621. Report an issue: GitHub.