{"record":{"id":"b853f66f62c159a4","repo":"elastic/elasticsearch","slug":"basebackoffmillis-must-be-0-but-was","errorCode":null,"errorMessage":"baseBackoffMillis must be >= 0 but was [{}]","messagePattern":"baseBackoffMillis must be >= 0 but was \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/HttpUtils.java","lineNumber":36,"sourceCode":"    private static final long HTTP_READ_RETRY_BACKOFF_MILLIS = 1000L;\n\n    private HttpUtils() {}\n\n    @FunctionalInterface\n    public interface Sleeper {\n        void sleep(long millis) throws InterruptedException;\n    }\n\n    public static byte[] readHttpBytesWithRetry(String url) throws IOException {\n        return readHttpBytesWithRetry(url, HTTP_READ_MAX_ATTEMPTS, HTTP_READ_RETRY_BACKOFF_MILLIS, Thread::sleep);\n    }\n\n    public static byte[] readHttpBytesWithRetry(String url, int maxAttempts, long baseBackoffMillis, Sleeper sleeper) throws IOException {\n        if (maxAttempts <= 0) {\n            throw new IllegalArgumentException(\"maxAttempts must be >= 1 but was [\" + maxAttempts + \"]\");\n        }\n        if (baseBackoffMillis < 0) {\n            throw new IllegalArgumentException(\"baseBackoffMillis must be >= 0 but was [\" + baseBackoffMillis + \"]\");\n        }\n\n        IOException lastException = null;\n        for (int attempt = 1; attempt <= maxAttempts; attempt++) {\n            if (attempt > 1 && baseBackoffMillis > 0) {\n                long backoff = baseBackoffMillis * (attempt - 1);\n                try {\n                    sleeper.sleep(backoff);\n                } catch (InterruptedException e) {\n                    Thread.currentThread().interrupt();\n                    throw new IOException(\"Interrupted while retrying download from: \" + url, e);\n                }\n            }\n\n            try (InputStream in = URI.create(url).toURL().openStream()) {\n                return in.readAllBytes();\n            } catch (IOException e) {\n                lastException = e;","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/util/HttpUtils.java#L18-L54","documentation":"HttpUtils.readHttpBytesWithRetry validates baseBackoffMillis >= 0 because the backoff is computed as baseBackoffMillis * (attempt-1) and a negative base would produce nonsensical (negative) sleep durations. The guard surfaces the invalid value directly.","triggerScenarios":"Calling readHttpBytesWithRetry with a negative baseBackoffMillis argument; a config typo or sign error feeding a negative long.","commonSituations":"Misconfigured retry backoff property; passing -1 as a 'disable backoff' sentinel instead of 0; arithmetic producing a negative value.","solutions":["Pass baseBackoffMillis = 0 to disable backoff, or a positive value to enable it.","Clamp configured values: Math.max(0, configuredBackoff) before calling.","Audit the source of the negative value — it usually indicates a config-resolution bug."],"exampleFix":"// before\nHttpUtils.readHttpBytesWithRetry(url, attempts, -100L, sleeper);\n// after\nHttpUtils.readHttpBytesWithRetry(url, attempts, 0L, sleeper); // 0 disables backoff","handlingStrategy":"validation","validationCode":"long safeBackoff = Math.max(0, configuredBackoff);\nHttpUtils.readHttpBytesWithRetry(url, attempts, safeBackoff, sleeper);","typeGuard":null,"tryCatchPattern":"try { HttpUtils.readHttpBytesWithRetry(url, attempts, backoff, sleeper); } catch (IllegalArgumentException e) { HttpUtils.readHttpBytesWithRetry(url); }","preventionTips":["Use 0 to disable backoff rather than negative sentinels.","Validate backoff config at load time.","Prefer the built-in defaults unless you have a measured reason to tune."],"tags":["validation","http","build","preconditions"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}