GoogleContainerTools/skaffold · error

failed to get default branch for repo %s

Error message

failed to get default branch for repo %s

What it means

When no ref is specified for a remote git dependency, defaultRef probes the remote with git ls-remote for a 'master' branch and then a 'main' branch. If neither ls-remote succeeds in finding either branch, it returns this error. It means skaffold could not determine which default branch to clone.

Source

Thrown at pkg/skaffold/git/gitutil.go:64

// defaultRef returns the default ref as "master" if master branch exists in
// remote repository, falls back to "main" if master branch doesn't exist
func defaultRef(ctx context.Context, repoCloneURI, repo string) (string, error) {
	masterRef := "master"
	mainRef := "main"
	masterExists, err := branchExists(ctx, repoCloneURI, repo, masterRef)
	if err != nil {
		return "", err
	}
	mainExists, err := branchExists(ctx, repoCloneURI, repo, mainRef)
	if err != nil {
		return "", err
	}
	if masterExists {
		return masterRef, nil
	} else if mainExists {
		return mainRef, nil
	}
	return "", fmt.Errorf("failed to get default branch for repo %s", repo)
}

// BranchExists checks if branch is present in the input repo
func branchExists(ctx context.Context, repoCloneURI, repo, branch string) (bool, error) {
	gitProgram, err := findGit()
	if err != nil {
		return false, err
	}
	out, err := util.RunCmdOut(ctx, exec.Command(gitProgram, "ls-remote", "--heads", repoCloneURI, branch))
	if err != nil {
		// stdErr contains the error message for os related errors, git permission errors
		// and if repo doesn't exist
		return false, fmt.Errorf("failed to lookup %s branch for repo %s: %w", branch, repo, err)
	}
	// stdOut contains the branch information if the branch is present in remote repo
	// stdOut is empty if the repo doesn't have the input branch
	if strings.TrimSpace(string(out)) != "" {
		return true, nil

View on GitHub (pinned to a1189de023)

Solutions

  1. Pin the ref explicitly in the skaffold git dependency config (git.Config.Ref) instead of relying on default detection.
  2. If the default branch has another name (e.g. trunk), set that name as the Ref.
  3. If the repo is empty, push at least one branch before using it as a dependency.
  4. Verify with git ls-remote --heads <repo> which branches actually exist remotely.

Example fix

// before
git:
  repo: https://github.com/org/repo
  # no ref -> default-branch probe fails
// after
git:
  repo: https://github.com/org/repo
  ref: trunk   # pin the actual default branch
Defensive patterns

Strategy: validation

Validate before calling

git ls-remote --heads https://github.com/org/repo | grep -E 'refs/heads/(master|main)$' \
  || echo "Neither master nor main exists; pin the ref explicitly in the skaffold git dependency"

Type guard

func hasPinnedRef(g git.Config) bool {
    return strings.TrimSpace(g.Ref) != ""
}

Try / catch

path, err := git.SyncRepo(ctx, cfg, opts)
if err != nil {
    if strings.Contains(err.Error(), "failed to get default branch for repo") {
        log.Warnf("no master/main on %s; pinning ref explicitly", cfg.Repo)
        cfg.Ref = detectBranchViaLsRemote(ctx, cfg.RepoCloneURI) // e.g. first head
        return git.SyncRepo(ctx, cfg, opts)
    }
    return err
}

Prevention

When it happens

Trigger: Calling syncRepo (via SyncRepo) with git.Config.Ref == "" for a repository whose remote has neither a master nor a main branch, so both branchExists probes return false with no error.

Common situations: Repos renamed default branch to something else (trunk, develop, mainline); repository is empty (no branches yet); bare/custom git server with unusual default branch.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/0d0fc32edf3911cd. Report an issue: GitHub.