{"record":{"id":"96d191285df718b8","repo":"apache/rocketmq","slug":"authentication-keyvalues-length-is-incorrect-actu","errorCode":null,"errorMessage":"authentication keyValues length is incorrect, actual length={}.","messagePattern":"authentication keyValues length is incorrect, actual length=(.+?)\\.","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"auth/src/main/java/org/apache/rocketmq/auth/authentication/builder/DefaultAuthenticationContextBuilder.java","lineNumber":71,"sourceCode":"            String authorization = metadata.get(GrpcConstants.AUTHORIZATION);\n            if (StringUtils.isEmpty(authorization)) {\n                return context;\n            }\n            String datetime = metadata.get(GrpcConstants.DATE_TIME);\n            if (StringUtils.isEmpty(datetime)) {\n                throw new AuthenticationException(\"datetime is null.\");\n            }\n\n            String[] result = authorization.split(CommonConstants.SPACE, 2);\n            if (result.length != 2) {\n                throw new AuthenticationException(\"authentication header is incorrect.\");\n            }\n            String[] keyValues = result[1].split(CommonConstants.COMMA);\n            for (String keyValue : keyValues) {\n                String[] kv = keyValue.trim().split(CommonConstants.EQUAL, 2);\n                int kvLength = kv.length;\n                if (kv.length != 2) {\n                    throw new AuthenticationException(\"authentication keyValues length is incorrect, actual length={}.\", kvLength);\n                }\n                String authItem = kv[0];\n                if (CREDENTIAL.equals(authItem)) {\n                    String[] credential = kv[1].split(CommonConstants.SLASH);\n                    int credentialActualLength = credential.length;\n                    if (credentialActualLength == 0) {\n                        throw new AuthenticationException(\"authentication credential length is incorrect, actual length={}.\", credentialActualLength);\n                    }\n                    context.setUsername(credential[0]);\n                    continue;\n                }\n                if (SIGNATURE.equals(authItem)) {\n                    context.setSignature(this.hexToBase64(kv[1]));\n                }\n            }\n\n            context.setContent(datetime.getBytes(StandardCharsets.UTF_8));\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/rocketmq/blob/293f5885719fc4aa3619446a1900f58ccfcfdd29/auth/src/main/java/org/apache/rocketmq/auth/authentication/builder/DefaultAuthenticationContextBuilder.java#L53-L89","documentation":"After splitting the credential section on commas, one comma-separated item did not contain a '=' separator (split with limit 2 produced fewer than 2 parts). Each item must be a key=value pair such as 'Credential=alice' or 'Signature=abc123', so a bare token like 'alice' or a trailing comma yields this error.","triggerScenarios":"Authorization header where any comma-separated item lacks '=', e.g. 'RocketMQ Credential=alice,,Signature=xyz' (empty item from double comma) or 'RocketMQ alice,Signature=xyz'.","commonSituations":"Manually concatenated headers with a stray/doubled comma; values containing unescaped commas splitting a pair; templating code that emits an empty pair when one component (e.g. signature) is null.","solutions":["Ensure every comma-separated item in the header is 'Key=Value' with non-empty key and value, and that there are no double commas or trailing commas.","Build the header by joining only the non-empty 'Credential=...', 'Signature=...', 'DateTime=...' parts.","Use the SDK-provided signer so pairs are always well-formed."],"exampleFix":"// before\nString auth = \"RocketMQ \" + Stream.of(cred, sig, dt).collect(joining(\",\")); // sig may be empty -> 'Credential=u,,DateTime=d'\n\n// after\nString auth = \"RocketMQ \" + Stream.of(cred, sig, dt).filter(s -> s != null && !s.isEmpty()).collect(joining(\",\"));","handlingStrategy":"validation","validationCode":"String[] pairs = {\"Credential=\" + user, \"Signature=\" + sig, \"DateTime=\" + dt};\nfor (String p : pairs) {\n    int eq = p.indexOf('=');\n    if (eq <= 0 || eq == p.length() - 1) throw new IllegalStateException(\"malformed auth pair: \" + p);\n}\nString header = \"RocketMQ \" + String.join(\",\", pairs);","typeGuard":null,"tryCatchPattern":"catch (AuthenticationException e) { log header shape (redacted values); treat as permanent client bug, do not retry. }","preventionTips":["Join only non-empty Key=Value parts when building the header","Fuzz the header builder with null/empty components in unit tests"],"tags":["rocketmq","authentication","header-format","parsing"],"backgroundTag":null,"analyzedSha":"293f5885719fc4aa3619446a1900f58ccfcfdd29","analyzedAt":"2026-08-14T11:50:13.822Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}