GoogleContainerTools/skaffold · error

failed to clone repo %s: trouble getting default branch: %w

Error message

failed to clone repo %s: trouble getting default branch: %w

What it means

Thrown by syncRepo when g.Ref is empty and defaultRef(ctx, g.RepoCloneURI, g.Repo) fails to determine the remote's default branch (it runs git ls-remote against the repo). syncRepo needs a ref to clone with when none is explicitly configured; the underlying git/network error is wrapped.

Source

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

	return base64.URLEncoding.EncodeToString(hasher.Sum(nil))[:32], nil
}

func syncRepo(ctx context.Context, g Config, opts config.SkaffoldOptions) (string, error) {
	skaffoldCacheDir, err := config.GetRemoteCacheDir(opts)
	r := gitCmd{Dir: skaffoldCacheDir}
	if err != nil {
		return "", fmt.Errorf("failed to clone repo %s: %w", g.Repo, err)
	}
	if err := os.MkdirAll(skaffoldCacheDir, 0700); err != nil {
		return "", fmt.Errorf(
			"failed to clone repo %s: trouble creating cache directory: %w", g.Repo, err)
	}

	ref := g.Ref
	if ref == "" {
		ref, err = defaultRef(ctx, g.RepoCloneURI, g.Repo)
		if err != nil {
			return "", fmt.Errorf("failed to clone repo %s: trouble getting default branch: %w", g.Repo, err)
		}
	}

	hash, err := getRepoDir(g)
	if err != nil {
		return "", fmt.Errorf("failed to clone git repo: unable to create directory name: %w", err)
	}
	repoCacheDir := filepath.Join(skaffoldCacheDir, hash)
	if _, err := os.Stat(repoCacheDir); os.IsNotExist(err) {
		if opts.SyncRemoteCache.CloneDisabled() {
			return "", SyncDisabledErr(g, repoCacheDir)
		}
		if _, err := r.Run(ctx, "clone", g.RepoCloneURI, fmt.Sprintf("./%s", hash), "--branch", ref, "--depth", "1"); err != nil {
			if strings.Contains(err.Error(), "Could not find remote branch") {
				if _, err := r.Run(ctx, "clone", g.RepoCloneURI, fmt.Sprintf("./%s", hash), "--depth", "1"); err != nil {
					return "", fmt.Errorf("failed to clone repo: %w", err)
				}

View on GitHub (pinned to a1189de023)

Solutions

  1. Explicitly set the ref in the git sync config so defaultRef is never called (e.g. ref: main).
  2. Run `git ls-remote <URL>` manually to reproduce and see the real error; fix credentials/network accordingly.
  3. Configure git credentials: ssh key added to ssh-agent, or HTTPS token via credential helper / GH_TOKEN.
  4. Verify the repo URL is reachable and correct; check proxy settings (HTTPS_PROXY) and connectivity.

Example fix

// before
sync:
  manual: [{src: 'src/**/*.go', dest: './'}]  # repo: https://github.com/org/repo (no ref)
// after
sync:
  manual: [{src: 'src/**/*.go', dest: './'}]  # repo: https://github.com/org/repo#main  (or set ref explicitly)
Defensive patterns

Strategy: validation

Validate before calling

const { execSync } = require('child_process');
function remoteReachable(uri) {
  try { execSync(`git ls-remote ${uri} HEAD`, { stdio: 'pipe' }); return true; }
  catch (e) { console.error('ls-remote failed:', e.stderr.toString()); return false; }
}

Type guard

function hasExplicitRef(gitSync) {
  return typeof gitSync.ref === 'string' && gitSync.ref.length > 0;
}

Try / catch

try {
  await syncRepo(g, ctx, opts);
} catch (err) {
  if (/trouble getting default branch/.test(err.message)) {
    // retry once with explicit ref after connectivity check
    g.ref = 'main';
    return syncRepo(g, ctx, opts);
  }
  throw err;
}

Prevention

When it happens

Trigger: syncRepo invoked with a GitInfo whose Ref field is empty, and the git ls-remote call in defaultRef fails (network failure, bad credentials, repo not found, git binary missing).

Common situations: Private repo without credentials configured (ssh key or token missing); typo in the remote-sync git URL; offline CI runner; corporate proxy blocking ls-remote; repo deleted or renamed on the remote.

Related errors


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