{"id":"19424aeec0fc94fc","repo":"apache/kafka","slug":"must-have-at-least-2-bins","errorCode":null,"errorMessage":"Must have at least 2 bins.","messagePattern":"Must have at least 2 bins\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/metrics/stats/Histogram.java","lineNumber":136,"sourceCode":"     * and the number of bins.\n     */\n    public static class ConstantBinScheme implements BinScheme {\n        private static final int MIN_BIN_NUMBER = 0;\n        private final double min;\n        private final int bins;\n        private final double bucketWidth;\n        private final int maxBinNumber;\n\n        /**\n         * Create a bin scheme with the specified number of bins that all have the same width.\n         *\n         * @param bins the number of bins; must be at least 2\n         * @param min the minimum value to be counted in the bins\n         * @param max the maximum value to be counted in the bins\n         */\n        public ConstantBinScheme(int bins, double min, double max) {\n            if (bins < 2)\n                throw new IllegalArgumentException(\"Must have at least 2 bins.\");\n            this.min = min;\n            this.bins = bins;\n            this.bucketWidth = (max - min) / bins;\n            this.maxBinNumber = bins - 1;\n        }\n\n        public int bins() {\n            return this.bins;\n        }\n\n        public double fromBin(int b) {\n            if (b < MIN_BIN_NUMBER) {\n                return Float.NEGATIVE_INFINITY;\n            }\n            if (b > maxBinNumber) {\n                return Float.POSITIVE_INFINITY;\n            }\n            return min + b * bucketWidth;","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/metrics/stats/Histogram.java#L118-L154","documentation":"Thrown by `Histogram.ConstantBinScheme`'s constructor when the requested bin count is less than 2. The scheme needs at least two bins because `bucketWidth = (max - min) / bins` must produce a positive, finite interval and because the value() percentile lookup iterates `hist.length - 1` bins. With one or zero bins the histogram collapses and percentile/frequency math becomes meaningless, so Kafka rejects the configuration at construction.","triggerScenarios":"Calling `new ConstantBinScheme(bins, min, max)` with `bins < 2`. Most commonly hit indirectly when `Percentiles` computes `buckets = sizeInBytes / 4` and `sizeInBytes` is less than 8 (so buckets resolves to 0 or 1), then constructs `new ConstantBinScheme(buckets, min, max)`.","commonSituations":"Passing a very small `sizeInBytes` to a `Percentiles` metric. Copying a metric configuration and trimming the bucket budget too aggressively. Misreading `sizeInBytes` as the number of buckets rather than bytes (4 bytes per bucket).","solutions":["Ensure `sizeInBytes` passed to Percentiles is at least 8 (yields 2 buckets); typically use 4096+ for meaningful percentiles.","If constructing ConstantBinScheme directly, pass `bins >= 2`.","Validate the computed bucket count in a unit test before creating the metric."],"exampleFix":"// before\nnew Percentiles(4, 100.0, BucketSizing.CONSTANT, p50, p99); // 4/4 = 1 bin\n\n// after\nnew Percentiles(4096, 100.0, BucketSizing.CONSTANT, p50, p99); // 1024 bins","handlingStrategy":"validation","validationCode":"if (bins < 2) {\n    throw new IllegalArgumentException(\"ConstantBinScheme requires bins >= 2, got \" + bins);\n}\nnew Histogram.ConstantBinScheme(bins, min, max);","typeGuard":null,"tryCatchPattern":"try {\n    binScheme = new Histogram.ConstantBinScheme(bins, min, max);\n} catch (IllegalArgumentException e) {\n    // \"Must have at least 2 bins.\"\n    bins = Math.max(bins, 2);\n    binScheme = new Histogram.ConstantBinScheme(bins, min, max);\n}","preventionTips":["Treat 2 as the hard floor for any bin count in this API; never derive bins from a divisor without clamping.","When computing bins from a byte size (e.g. Percentiles does sizeInBytes/4), assert the result is >= 2 before passing downstream.","Centralize bin-count derivation in a helper that enforces the minimum, so call sites cannot smuggle in a 1 or 0."],"tags":["metrics","histogram","percentiles","configuration","validation","java"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}