{"record":{"id":"c5a2bbbff48a308e","repo":"aeron-io/aeron","slug":"gaplength-must-be-smaller-than-gapradix","errorCode":null,"errorMessage":"gapLength must be smaller than gapRadix","messagePattern":"gapLength must be smaller than gapRadix","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"aeron-driver/src/main/java/io/aeron/driver/ext/MultiGapLossGenerator.java","lineNumber":56,"sourceCode":"    /**\n     * Set the range of messages to be dropped.\n     *\n     * @param termId     to be dropped\n     * @param gapRadix   the initial offset and subsequent interval between gaps - must be a power of 2\n     * @param gapLength  length of each gap\n     * @param totalGaps  the total number of gaps\n     */\n    public MultiGapLossGenerator(\n        final int termId,\n        final int gapRadix,\n        final int gapLength,\n        final int totalGaps)\n    {\n        final int actualGapRadix = BitUtil.findNextPositivePowerOfTwo(gapRadix);\n\n        if (gapLength >= actualGapRadix)\n        {\n            throw new IllegalArgumentException(\"gapLength must be smaller than gapRadix\");\n        }\n\n        this.termId = termId;\n        this.gapRadixBits = Integer.numberOfTrailingZeros(actualGapRadix);\n        this.gapRadixMask = -actualGapRadix;\n        this.gapLength = gapLength;\n        this.lastGapLimit = (totalGaps * actualGapRadix) + gapLength;\n    }\n\n    /**\n     * {@inheritDoc}\n     */\n    @Override\n    public boolean shouldDropFrame(final InetSocketAddress address, final UnsafeBuffer buffer, final int length)\n    {\n        return false;\n    }\n","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-driver/src/main/java/io/aeron/driver/ext/MultiGapLossGenerator.java#L38-L74","documentation":"MultiGapLossGenerator (a driver testing/loss-injection utility) constructs gaps aligned to a gapRadix that must be a positive power of two and strictly greater than gapLength. If gapLength >= the normalized gapRadix, the constructor throws IllegalArgumentException, because a gap cannot fit within the radix-aligned window it belongs to.","triggerScenarios":"Constructing MultiGapLossGenerator with gapLength equal to or larger than gapRadix (e.g. gapLength=64, gapRadix=64), or with a gapRadix that is not a power of two (silently rounded down by findNextPositivePowerOfTwo, making actualGapRadix smaller than expected and smaller than gapLength).","commonSituations":"Configuring loss injection for testing with values like gapLength==gapRadix, or passing gapRadix=100 (rounded to 64) while gapLength stays at 80 — the rounding makes an otherwise-valid-looking configuration invalid.","solutions":["Set gapLength strictly smaller than gapRadix, e.g. gapLength=32 with gapRadix=64.","Ensure gapRadix is a power of two (64, 128, 256...) so it is not rounded down below gapLength.","Validate parameters before constructing: assert gapLength < BitUtil.findNextPositivePowerOfTwo(gapRadix).","If you want gaps spanning the whole radix, increase gapRadix to the next power of two above gapLength."],"exampleFix":"// before\nnew MultiGapLossGenerator(termId, termLength, 64, 64, 3); // gapLength == gapRadix\n// after\nnew MultiGapLossGenerator(termId, termLength, 32, 64, 3); // gapLength < gapRadix","handlingStrategy":"validation","validationCode":"import io.aeron.driver.ext.MultiGapLossGenerator;\nimport org.agrona.BitUtil;\nint radix = BitUtil.findNextPositivePowerOfTwo(gapRadix);\nif (gapLength >= radix) {\n    throw new IllegalArgumentException(\n        \"gapLength (\" + gapLength + \") must be < next power of two of gapRadix (\" + radix + \")\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    new MultiGapLossGenerator(termId, termLength, gapLength, gapRadix, totalGaps);\n} catch (IllegalArgumentException e) {\n    // correct gapLength/gapRadix values before retrying\n}","preventionTips":["Always pick gapRadix as an explicit power of two (64, 128, 256).","Keep gapLength at most half of gapRadix in test configs.","Unit-test loss-generator parameters before wiring them into driver loss injection.","Remember gapRadix is rounded down to the next power of two — pass exact powers of two to avoid surprises."],"tags":["java","illegal-argument","validation","testing"],"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-15T23:17:13.987Z"}