apache/rocketmq · error · AuthenticationException

authentication header is incorrect.

Error message

authentication header is incorrect.

What it means

The Authorization header was split on a single space with limit 2 and did not yield two parts. The expected format is a scheme token followed by the credential string, i.e. 'RocketMQ Credential=<user>,Signature=<sig>,DateTime=<datetime>'. Any header lacking the scheme prefix (or lacking any space) makes result.length != 2 and this exception is thrown.

Source

Thrown at auth/src/main/java/org/apache/rocketmq/auth/authentication/builder/DefaultAuthenticationContextBuilder.java:64

    @Override
    public DefaultAuthenticationContext build(Metadata metadata, GeneratedMessageV3 request) {
        try {
            DefaultAuthenticationContext context = new DefaultAuthenticationContext();
            context.setChannelId(metadata.get(GrpcConstants.CHANNEL_ID));
            context.setRpcCode(request.getDescriptorForType().getFullName());
            String authorization = metadata.get(GrpcConstants.AUTHORIZATION);
            if (StringUtils.isEmpty(authorization)) {
                return context;
            }
            String datetime = metadata.get(GrpcConstants.DATE_TIME);
            if (StringUtils.isEmpty(datetime)) {
                throw new AuthenticationException("datetime is null.");
            }

            String[] result = authorization.split(CommonConstants.SPACE, 2);
            if (result.length != 2) {
                throw new AuthenticationException("authentication header is incorrect.");
            }
            String[] keyValues = result[1].split(CommonConstants.COMMA);
            for (String keyValue : keyValues) {
                String[] kv = keyValue.trim().split(CommonConstants.EQUAL, 2);
                int kvLength = kv.length;
                if (kv.length != 2) {
                    throw new AuthenticationException("authentication keyValues length is incorrect, actual length={}.", kvLength);
                }
                String authItem = kv[0];
                if (CREDENTIAL.equals(authItem)) {
                    String[] credential = kv[1].split(CommonConstants.SLASH);
                    int credentialActualLength = credential.length;
                    if (credentialActualLength == 0) {
                        throw new AuthenticationException("authentication credential length is incorrect, actual length={}.", credentialActualLength);
                    }
                    context.setUsername(credential[0]);
                    continue;
                }

View on GitHub (pinned to 293f588571)

Solutions

  1. Format the header as 'RocketMQ Credential=<username>,Signature=<signature>,DateTime=<datetime>' with exactly one space after the RocketMQ scheme word.
  2. Delegate header construction to the client SDK's built-in signer/interceptor rather than building the string manually.
  3. Log the outgoing authorization header (redacted) once to confirm it starts with 'RocketMQ '.

Example fix

// before
String authorization = "Credential=" + user + ",Signature=" + sig;

// after
String authorization = "RocketMQ Credential=" + user + ",Signature=" + sig + ",DateTime=" + datetime;
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern AUTH_HEADER = Pattern.compile("^RocketMQ \S+=\S+(,\S+=\S+)*$");
if (!AUTH_HEADER.matcher(authorization).matches()) {
    throw new IllegalArgumentException("authorization must be 'RocketMQ Credential=...,Signature=...,DateTime=...'");
}

Try / catch

catch (AuthenticationException e) { if (e.getMessage().contains("header is incorrect")) fail fast with a config error - this is never transient; rethrow otherwise. }

Prevention

When it happens

Trigger: Calling a gRPC API with authorization metadata such as 'Credential=abc,Signature=xyz' (missing the leading 'RocketMQ ' scheme token), an empty scheme, or multiple spaces misplacing the split so that only one token results.

Common situations: Custom clients copying the AWS-style header without the 'RocketMQ' scheme; SDKs upgraded from 4.x to 5.x where the ACL header format changed; test harnesses hard-coding a malformed header.

Understand the failure class

Related errors


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