elastic/elasticsearch · error · GradleException

Failed to fetch branch

Error message

Failed to fetch branch {normalizedBranch} from {sourceRepo} for external changelogs

What it means

Thrown by BundleChangelogsTask when fetching an external changelog source (a separate repo) fails. The task runs `git fetch [--depth=1] <repoUrl> <branch>` inside a try; any Exception (network error, ref-not-found, auth) is caught and rethrown as a GradleException naming the normalized branch and source repo so the developer knows which external source failed.

Solutions

  1. Verify the external branch name exists on the configured sourceRepo (normalizeBranchForExternalFetch strips known prefixes — pass a plain branch name).
  2. Confirm network access and git credentials for the external repoUrl (try `git ls-remote <repoUrl>` manually).
  3. If running offline, fetch the external sources beforehand or remove the external source from the bundling config for this run.
  4. Re-run bundleChangelogs after correcting the branch/credentials.
Defensive patterns

Strategy: try-catch

Validate before calling

// Preflight: verify the external ref is fetchable
try {
    gitRun("ls-remote", sourceRepo.repoUrl(), normalizedBranch);
} catch (Exception e) {
    throw new IllegalStateException("External branch not reachable: " + normalizedBranch, e);
}

Try / catch

try { fetchExternal(source); }
catch (GradleException e) {
    // inspect cause: network vs missing ref vs auth; fix and retry, don't silently skip
    throw e;
}

Prevention

When it happens

Trigger: An external changelog source configured in the bundling spec specifies a repoUrl and branch; the git fetch for that source fails — wrong branch name, no network, missing permissions, or the ref doesn't exist on the remote. The catch wraps the original exception.

Common situations: Typo in the external branch name; the external repo/branch was renamed or deleted; network/firewall blocking the fetch; SSH/HTTPS credentials not configured for the external remote; running offline.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/551b5c1bfecc0e50. Report an issue: GitHub.

Appendix: source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java:293

            return List.of();
        }
        String normalizedBranch = normalizeBranchForExternalFetch(branchRef, esUpstreamRemote);

        try {
            if (bcRefForFilter != null && bcRefForFilter.isBlank() == false) {
                // Full history: shallow fetch can hide PR merges older than --depth from FETCH_HEAD,
                // causing BC grep filtering to drop valid external changelog entries.
                LOGGER.info(
                    "Fetching full history from {}:{} for BC filtering (may be slower than shallow fetch)",
                    source.sourceRepo(),
                    normalizedBranch
                );
                gitWrapper.runCommand("git", "fetch", source.repoUrl(), normalizedBranch);
            } else {
                gitWrapper.runCommand("git", "fetch", "--depth=1", source.repoUrl(), normalizedBranch);
            }
        } catch (Exception e) {
            throw new GradleException(
                "Failed to fetch branch " + normalizedBranch + " from " + source.sourceRepo() + " for external changelogs",
                e
            );
        }

        String externalHead = gitWrapper.runCommand("git", "rev-parse", "FETCH_HEAD").trim();

        String treePath = source.changelogPath();

        List<String> files;
        try {
            files = gitWrapper.listFiles("FETCH_HEAD", treePath).filter(f -> f.endsWith(".yaml")).toList();
        } catch (Exception e) {
            LOGGER.warn("No changelog directory found at {} in {}:{}", treePath, source.sourceRepo(), normalizedBranch);
            return List.of();
        }

        if (files.isEmpty()) {

View on GitHub (pinned to db6a809a66)