alibaba/nacos · error · AccessException

Invalid signature

Error message

Invalid signature

What it means

Thrown by NacosSignatureAlgorithm.verify(header, payload, signature, key) as an AccessException when the recomputed HMAC over (header + '.' + payload) does not equal the signature carried in the token. A signature mismatch means the key used to verify differs from the key used to sign, or the token was tampered with.

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/jwt/NacosSignatureAlgorithm.java:134

    }
    
    /**
     * verify jwt.
     *
     * @param header    header of jwt
     * @param payload   payload of jwt
     * @param signature signature of jwt
     * @param key       for signature
     * @return object for payload
     * @throws AccessException access exception
     */
    public NacosUser verify(String header, String payload, String signature, Key key)
        throws AccessException {
        Mac macInstance = getMacInstance(key);
        byte[] bytes = macInstance
            .doFinal((header + JWT_SEPERATOR + payload).getBytes(StandardCharsets.US_ASCII));
        if (!URL_BASE64_ENCODER.encodeToString(bytes).equals(signature)) {
            throw new AccessException("Invalid signature");
        }
        NacosJwtPayload nacosJwtPayload =
            JacksonUtils.toObj(URL_BASE64_DECODER.decode(payload), NacosJwtPayload.class);
        if (nacosJwtPayload.getExp() >= TimeUnit.MILLISECONDS
            .toSeconds(System.currentTimeMillis())) {
            return new NacosUser(nacosJwtPayload.getSub());
        }
        
        throw new AccessException("token expired!");
    }
    
    /**
     * get jwt expire time in seconds.
     *
     * @param jwt complete jwt string
     * @param key for signature
     * @return expire time in seconds
     * @throws AccessException access exception

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Ensure all Nacos server nodes share the identical token.secret.key.
  2. After key rotation, re-issue tokens so clients carry signatures from the current key.
  3. Confirm the secret key was not truncated/altered when deployed (compare base64 across nodes).

Example fix

// before: nodes have divergent keys
node-A: token.secret.key=KeyAAAA...
node-B: token.secret.key=KeyBBBB...
// token signed by A fails signature check on B

// after: identical key on all nodes
node-A: token.secret.key=SharedKey...
node-B: token.secret.key=SharedKey...
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the verifying key matches the signing key before issuing tokens.
byte[] signed = macSign(testPayload, signingKey);
if (!MessageDigest.isEqual(signed, macSign(testPayload, verifyingKey))) {
    throw new IllegalStateException("Signing and verifying keys differ");
}

Try / catch

try {
    NacosUser user = NacosSignatureAlgorithm.verify(jwt, key);
} catch (AccessException e) {
    if ("Invalid signature".equals(e.getMessage())) {
        // key mismatch or tampering — force client to re-login
    }
    throw e;
}

Prevention

When it happens

Trigger: getMacInstance(key) computes the HMAC with the configured secret key; URL_BASE64_ENCODER.encodeToString(mac.doFinal(...)).equals(signature) is false, so the throw fires.

Common situations: token.secret.key was rotated and old clients still present tokens signed by the previous key; a multi-node cluster where nodes have different secret keys; token tampering (man-in-the-middle); wrong key configured on the verifying node.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/fe17421e71905d69. Report an issue: GitHub.