{"record":{"id":"c0f0d79e85354bd8","repo":"elastic/elasticsearch","slug":"failed-to-download-branches-json-from","errorCode":null,"errorMessage":"Failed to download branches.json from: {}","messagePattern":"Failed to download branches\\.json from: (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java","lineNumber":248,"sourceCode":"            } else {\n                throw new GradleException(\n                    \"Gradle is running in offline mode, but branches.json location [\"\n                        + configuredBranchesFileLocation\n                        + \"] is an http(s) URL and no local branches.json was found at [\"\n                        + localBranchesFile\n                        + \"]. Either disable offline mode, set -P\"\n                        + BRANCHES_FILE_LOCATION_PROPERTY\n                        + \"=<local file path>, or create branches.json at the workspace root.\"\n                );\n            }\n        }\n        LOGGER.info(\"Reading branches.json from {}\", branchesFileLocation);\n        byte[] branchesBytes;\n        if (isHttpLocation(branchesFileLocation)) {\n            try {\n                branchesBytes = HttpUtils.readHttpBytesWithRetry(branchesFileLocation);\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Failed to download branches.json from: \" + branchesFileLocation, e);\n            }\n        } else {\n            try {\n                branchesBytes = Files.readAllBytes(new File(branchesFileLocation).toPath());\n            } catch (IOException e) {\n                throw new UncheckedIOException(\"Failed to read branches.json from: \" + branchesFileLocation, e);\n            }\n        }\n\n        var branchesFileParser = new BranchesFileParser(new ObjectMapper());\n        return branchesFileParser.parse(branchesBytes);\n    }\n\n    private static boolean isHttpLocation(String branchesFileLocation) {\n        return branchesFileLocation.startsWith(\"http://\") || branchesFileLocation.startsWith(\"https://\");\n    }\n\n    private void logGlobalBuildInfo(BuildParameterExtension buildParams) {","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java#L230-L266","documentation":"Thrown by GlobalBuildInfoPlugin.getDevelopmentBranches() when downloading branches.json from an http(s) URL fails. The download is performed by HttpUtils.readHttpBytesWithRetry(location), which attempts the download and retries. If all attempts fail with IOException, it is wrapped in UncheckedIOException. This only occurs when branchesFileLocation starts with http:// or https://.","triggerScenarios":"branchesFileLocation is an http(s) URL (the default or set via -Pbranches.file.location=https://...). HttpUtils.readHttpBytesWithRetry exhausts retries and throws IOException. Causes include DNS resolution failure, connection refused, HTTP 404/500, read timeout, or TLS handshake failure.","commonSituations":"The build runs in an environment without internet access (but not in --offline mode, which has its own error path). The URL is wrong or the hosting server is down. A corporate proxy blocks the request. TLS certificate issues on the hosting endpoint.","solutions":["Verify network connectivity: curl -I <branches.json URL>.","If behind a proxy, configure Gradle's proxy settings in gradle.properties or pass -Dhttps.proxyHost/-Dhttps.proxyPort.","Use a local file instead: -Pbranches.file.location=/path/to/branches.json.","Switch to --offline mode and place branches.json at the workspace root."],"exampleFix":"# before\n./gradlew build  # tries to download from default URL, network blocked\n\n# after (local file)\n./gradlew build -Pbranches.file.location=/home/user/branches.json\n\n# after (offline with local copy)\ncp /shared/branches.json branches.json\n./gradlew build --offline","handlingStrategy":"retry","validationCode":"// Validate network connectivity before build\ntry {\n    HttpUtils.readHttpBytesWithRetry(branchesFileLocation);\n} catch (IOException e) {\n    logger.warn(\"Cannot reach branches.json URL, falling back to local file\");\n    branchesFileLocation = new File(workspaceDir, \"branches.json\").getAbsolutePath();\n}","typeGuard":null,"tryCatchPattern":"try {\n    branchesBytes = HttpUtils.readHttpBytesWithRetry(branchesFileLocation);\n} catch (IOException e) {\n    // Fallback to local file\n    File local = new File(workspaceDir, \"branches.json\");\n    if (local.exists()) {\n        branchesBytes = Files.readAllBytes(local.toPath());\n    } else {\n        throw new UncheckedIOException(\"Failed to download and no local fallback\", e);\n    }\n}","preventionTips":["Maintain a local copy of branches.json for network failure resilience.","Configure HTTP proxy settings in gradle.properties if behind a corporate proxy.","Use --offline mode with a local branches.json in air-gapped environments."],"tags":["network","branches","http","download","io"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}