{"record":{"id":"93ca74ad2a93cbaf","repo":"aeron-io/aeron","slug":"overflow-totallength-totallength","errorCode":null,"errorMessage":"overflow totalLength={totalLength}","messagePattern":"overflow totalLength=(.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-client/src/main/java/io/aeron/Publication.java","lineNumber":732,"sourceCode":"        }\n    }\n\n    static int validateAndComputeLength(final int lengthOne, final int lengthTwo)\n    {\n        if (lengthOne < 0)\n        {\n            throw new IllegalArgumentException(\"lengthOne < 0: \" + lengthOne);\n        }\n\n        if (lengthTwo < 0)\n        {\n            throw new IllegalArgumentException(\"lengthTwo < 0: \" + lengthTwo);\n        }\n\n        final int totalLength = lengthOne + lengthTwo;\n        if (totalLength < 0)\n        {\n            throw new IllegalArgumentException(\"overflow totalLength=\" + totalLength);\n        }\n\n        return totalLength;\n    }\n\n    /**\n     * Returns a string representation of a position. Generally used for errors. If the position is a valid error then\n     * String name of the error will be returned. If the value is 0 or greater the text will be \"NONE\". If the position\n     * is negative, but not a known error code then \"UNKNOWN\" will be returned.\n     *\n     * @param position position value returned from a call to offer.\n     * @return String representation of the error.\n     */\n    public static String errorString(final long position)\n    {\n        if (MAX_POSITION_EXCEEDED <= position && position < 0)\n        {\n            final int errorCode = (int)position;","sourceCodeStart":714,"sourceCodeEnd":750,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/Publication.java#L714-L750","documentation":"Thrown by Publication.validateAndComputeLength when the sum of the two vectored lengths overflows int (totalLength < 0). Both component lengths were individually non-negative but their sum exceeds Integer.MAX_VALUE; Aeron computes the total as an int to size the resulting frame.","triggerScenarios":"publication.offer(...) with two buffers whose combined length exceeds 2^31 - 1 — only reachable with near-2GB buffers, but possible with miscomputed lengths (e.g. accidentally adding capacity instead of remaining()).","commonSituations":"Very large batched sends combining header and near-Integer.MAX_VALUE payloads; accidental use of buffer.capacity() rather than remaining() when computing lengths; test code constructing extreme sizes.","solutions":["Compute the total as a long and check it against Integer.MAX_VALUE (and maxMessageLength) before the offer.","Fix length computations to use remaining() rather than capacity(), avoiding inflated totals.","Split very large vectored sends into multiple offers within maxMessageLength()."],"exampleFix":"// before\npublication.offer(buf1, 0, len1, buf2, 0, len2); // len1 + len2 overflows int\n\n// after\nlong total = (long) len1 + len2;\nif (total < 0 || total > Integer.MAX_VALUE)\n{\n    throw new IllegalArgumentException(\"vectored total too large: \" + total);\n}\npublication.offer(buf1, 0, len1, buf2, 0, len2);","handlingStrategy":"validation","validationCode":"long total = (long) lengthOne + lengthTwo;\nif (total < 0 || total > publication.maxMessageLength()) { throw new IllegalArgumentException(\"vectored total too large: \" + total); }","typeGuard":"boolean fitsVectoredTotal(Publication p, int lengthOne, int lengthTwo) { return ((long) lengthOne + lengthTwo) >= 0 && ((long) lengthOne + lengthTwo) <= p.maxMessageLength(); }","tryCatchPattern":"try\n{\n    publication.offer(buf1, off1, len1, buf2, off2, len2);\n}\ncatch (IllegalArgumentException e)\n{\n    // int overflow or oversized total: split the send into multiple offers\n    log.error(\"vectored offer too large\", e);\n}","preventionTips":["Sum lengths in long before any int arithmetic to detect overflow early.","Use remaining() rather than capacity() when measuring buffers.","Cap vectored sends at maxMessageLength() and split beyond that.","Add overflow unit tests for any length-aggregation helper."],"tags":["aeron","publication","integer-overflow","vectored-offer"],"backgroundTag":"value-out-of-range","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}