GoogleContainerTools/skaffold · error

failed to clone repo %s: remote not set for existing clone

Error message

failed to clone repo %s: remote not set for existing clone

What it means

Thrown by syncRepo when the cached clone exists and `git remote -v` succeeds but returns no remotes — meaning the cached directory is a git repo with no 'origin' configured. syncRepo requires the remote to fetch updates, so the cache is considered unusable. Note this is a plain error (no %w), triggered when len(remotes) == 0.

Source

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

				r.Dir = repoCacheDir
				if _, err := r.Run(ctx, "checkout", ref); err != nil {
					if rmErr := os.RemoveAll(repoCacheDir); rmErr != nil {
						err = fmt.Errorf("failed to remove repo cache dir: %w", rmErr)
					}

					return "", fmt.Errorf("failed to checkout commit: %w", err)
				}
			} else {
				return "", fmt.Errorf("failed to clone repo: %w", err)
			}
		}
	} else {
		r.Dir = repoCacheDir
		// check remote is defined
		if remotes, err := r.Run(ctx, "remote", "-v"); err != nil {
			return "", fmt.Errorf("failed to clone repo %s: trouble checking repository remote; run 'git clone <REPO>; stat <DIR/SUBDIR>' to verify credentials: %w", g.Repo, err)
		} else if len(remotes) == 0 {
			return "", fmt.Errorf("failed to clone repo %s: remote not set for existing clone", g.Repo)
		}

		// if sync property is false, then skip fetching latest from remote and resetting the branch.
		if g.Sync != nil && !*g.Sync {
			return repoCacheDir, nil
		}

		// if sync is turned off via flag `--sync-remote-cache`, then skip fetching latest from remote and resetting the branch.
		if opts.SyncRemoteCache.FetchDisabled() {
			return repoCacheDir, nil
		}

		tryUpdateRemoteOriginFetchURL(ctx, r, g.RepoCloneURI)

		if _, err = r.Run(ctx, "fetch", "origin", ref); err != nil {
			return "", fmt.Errorf("failed to clone repo %s: unable to find any matching refs %s; run 'git clone <REPO>; stat <DIR/SUBDIR>' to verify credentials: %w", g.Repo, ref, err)
		}

View on GitHub (pinned to a1189de023)

Solutions

  1. Delete the cached clone (rm -rf <remote-cache-dir>/<hash>) and re-run so skaffold performs a real clone with origin set.
  2. If keeping the dir, add the remote manually: git -C <cachedir> remote add origin <RepoCloneURI>.
  3. Check for tooling/scripts that init the cache dir without cloning and fix them.
  4. Pre-create nothing: let skaffold manage its own cache dir contents.

Example fix

# before
ls ~/.skaffold/gitcache/<hash>  # git repo with no origin
# after
rm -rf ~/.skaffold/gitcache/<hash>  # or: git -C ~/.skaffold/gitcache/<hash> remote add origin <url>
Defensive patterns

Strategy: validation

Validate before calling

const { execSync } = require('child_process');
function hasOrigin(dir) {
  try {
    const out = execSync(`git -C ${dir} remote get-url origin`, { encoding: 'utf8' });
    return out.trim().length > 0;
  } catch { return false; }
}
// before running skaffold: if (fs.existsSync(cacheDirHash) && !hasOrigin(cacheDirHash)) fs.rmSync(cacheDirHash, {recursive:true});

Type guard

null

Try / catch

try {
  await syncRepo(g, ctx, opts);
} catch (err) {
  if (/remote not set for existing clone/.test(err.message)) {
    fs.rmSync(path.join(cacheDir, hashFor(g)), { recursive: true, force: true });
    return syncRepo(g, ctx, opts); // fresh clone will set origin
  }
  throw err;
}

Prevention

When it happens

Trigger: Existing repoCacheDir is a git repo without configured remotes — e.g. created by `git init` instead of `git clone`, or remotes stripped out, or git remote -v output empty.

Common situations: Cache directory seeded manually or by an older tool version; someone ran git remote remove origin; cache dir copied/transferred losing config; container image baked with an init'd but unremote'd repo.

Related errors


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