elastic/elasticsearch · error · GradleException

Failed to fetch branch {normalizedBranch} from {sourceRepo}

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.

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)

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.