apache/rocketmq · error · AuthenticationException

check signature failed.

Error message

check signature failed.

What it means

Signature verification failed: the server recomputed HMAC (AclSigner.calSignature over the datetime content with the stored user password) and it does not constant-time-match the client-supplied signature (or the client sent none). The credential was parsed and the user exists, so this specifically means secret mismatch or content/signature divergence.

Source

Thrown at auth/src/main/java/org/apache/rocketmq/auth/authentication/chain/DefaultAuthenticationHandler.java:68

            throw new AuthenticationException("The authenticationMetadataProvider is not configured");
        }
        if (StringUtils.isEmpty(context.getUsername())) {
            throw new AuthenticationException("username cannot be null.");
        }
        return this.authenticationMetadataProvider.getUser(context.getUsername());
    }

    protected void doAuthenticate(DefaultAuthenticationContext context, User user) {
        if (user == null) {
            throw new AuthenticationException("User:{} is not found.", context.getUsername());
        }
        if (user.getUserStatus() == UserStatus.DISABLE) {
            throw new AuthenticationException("User:{} is disabled.", context.getUsername());
        }
        String signature = AclSigner.calSignature(context.getContent(), user.getPassword());
        if (context.getSignature() == null
            || !MessageDigest.isEqual(signature.getBytes(AclSigner.DEFAULT_CHARSET), context.getSignature().getBytes(AclSigner.DEFAULT_CHARSET))) {
            throw new AuthenticationException("check signature failed.");
        }
    }
}

View on GitHub (pinned to 293f588571)

Solutions

  1. Ensure the client secret matches the server-stored password for that user (re-enter or re-create the credential pair).
  2. Sign exactly the same datetime string that is put into the datetime metadata, using HMAC-SHA256 then hex encoding, i.e. replicate AclSigner.calSignature semantics.
  3. Verify no intermediary alters the datetime or authorization metadata between signing and arrival; synchronize clocks if the signed timestamp is generated twice.

Example fix

// before: signs a freshly generated timestamp, then sends a different one
String sig = sign(LocalDateTime.now() ...);
metadata.put(DATETIME, LocalDateTime.now() ...); // second now() differs

// after
String datetime = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneOffset.UTC).format(Instant.now());
String sig = hexHmacSha256(datetime.getBytes(UTF_8), secretKey);
metadata.put(DATETIME, datetime);
metadata.put(AUTHORIZATION, "RocketMQ Credential=" + user + ",Signature=" + sig);
Defensive patterns

Strategy: validation

Validate before calling

// Reuse the exact datetime for metadata AND signature
String datetime = DateTimeFormatter.ofPattern("yyyyMMddHHmmss")
        .withZone(ZoneOffset.UTC).format(Instant.now());
String signature = hex(HmacSHA256(datetime.getBytes(StandardCharsets.UTF_8), secretKey));
assert signature != null && !signature.isEmpty();

Try / catch

catch (AuthenticationException e) { if message contains "check signature failed" -> re-verify secret against server record and clock sync; one retry with fresh datetime, then surface a credentials-config alert. }

Prevention

When it happens

Trigger: Client signs the datetime string with the wrong secret (password changed server-side), signs different content than the datetime metadata it sends, or produces the signature in a different encoding (base64 vs hex). Also thrown when the signature pair is missing entirely, making context.getSignature() null.

Common situations: Password rotated on the broker but client still uses the old secret; client clock skew where a different datetime string is signed than transmitted; custom clients not replicating AclSigner's HMAC-SHA256 + hex; a proxy rewriting the datetime header.

Related errors


AI-assisted analysis of apache/rocketmq@293f588571 (2026-08-14). Data as JSON: /api/errors/dd23d27b11bf2b3b. Report an issue: GitHub.