{"record":{"id":"2717abc2f1dd43b7","repo":"aeron-io/aeron","slug":"token-length-must-be-0-tokenlength","errorCode":null,"errorMessage":"token length must be >= 0: {tokenLength}","messagePattern":"token length must be >= 0: (.+?)","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/command/TerminateDriverFlyweight.java","lineNumber":159,"sourceCode":"\n        if ((length - MINIMUM_LENGTH) < buffer.getInt(offset + TOKEN_LENGTH_OFFSET))\n        {\n            throw new ControlProtocolException(\n                MALFORMED_COMMAND, \"command=\" + msgTypeId + \" too short for token buffer: length=\" + length);\n        }\n    }\n\n    /**\n     * Compute the length of the command message for a given token length.\n     *\n     * @param tokenLength to be appended to the header.\n     * @return the length of the command message for a given token length.\n     */\n    public static int computeLength(final int tokenLength)\n    {\n        if (tokenLength < 0)\n        {\n            throw new ConfigurationException(\"token length must be >= 0: \" + tokenLength);\n        }\n\n        return LENGTH + SIZE_OF_INT + tokenLength;\n    }\n}\n","sourceCodeStart":141,"sourceCodeEnd":165,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/command/TerminateDriverFlyweight.java#L141-L165","documentation":"TerminateDriverFlyweight.computeLength computes the total command size as LENGTH + SIZE_OF_INT + tokenLength. A negative tokenLength has no meaning and would corrupt the encoding, so a ConfigurationException is thrown eagerly. Unlike the protocol checks this happens at encode time on the caller's side.","triggerScenarios":"Calling computeLength (or an encoder that uses it, e.g. when terminating a driver with an authentication token) with a negative token buffer length.","commonSituations":"Bugs where token length is derived from an uninitialized variable or a failed read returning -1; subtracting offsets in the wrong order.","solutions":["Fix the code producing the token length; only pass tokenLength >= 0 (e.g. Math.max(0, bytes.length)).","If no token is needed, pass 0 rather than a sentinel negative value.","Add an assertion or pre-check on token length before calling computeLength."],"exampleFix":"// before\nint len = TerminateDriverFlyweight.computeLength(tokenBytes.length - overhead);\n// after\nint tokenLen = Math.max(0, tokenBytes == null ? 0 : tokenBytes.length);\nint len = TerminateDriverFlyweight.computeLength(tokenLen);","handlingStrategy":"validation","validationCode":"if (tokenLength < 0) { throw new IllegalArgumentException(\"tokenLength must be >= 0\"); }\nint length = TerminateDriverFlyweight.computeLength(tokenLength);","typeGuard":null,"tryCatchPattern":"try { int len = TerminateDriverFlyweight.computeLength(tokenLength); } catch (ConfigurationException e) { /* negative token length */ }","preventionTips":["Never pass sentinel negative lengths; use 0 for no token","Guard any computed token length with Math.max(0, ...)","Assert token buffer reads succeeded before computing length"],"tags":["aeron","configuration","token"],"backgroundTag":"invalid-argument-value","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}