{"record":{"id":"d268a779c8598e6b","repo":"GoogleContainerTools/skaffold","slug":"failed-to-clone-repo-s-trouble-checking-reposito","errorCode":null,"errorMessage":"failed to clone repo %s: trouble checking repository remote; run 'git clone <REPO>; stat <DIR/SUBDIR>' to verify credentials: %w","messagePattern":"failed to clone repo (.+?): trouble checking repository remote; run 'git clone <REPO>; stat <DIR/SUBDIR>' to verify credentials: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/git/gitutil.go","lineNumber":149,"sourceCode":"\t\t\t\t}\n\n\t\t\t\tr.Dir = repoCacheDir\n\t\t\t\tif _, err := r.Run(ctx, \"checkout\", ref); err != nil {\n\t\t\t\t\tif rmErr := os.RemoveAll(repoCacheDir); rmErr != nil {\n\t\t\t\t\t\terr = fmt.Errorf(\"failed to remove repo cache dir: %w\", rmErr)\n\t\t\t\t\t}\n\n\t\t\t\t\treturn \"\", fmt.Errorf(\"failed to checkout commit: %w\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo: %w\", err)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tr.Dir = repoCacheDir\n\t\t// check remote is defined\n\t\tif remotes, err := r.Run(ctx, \"remote\", \"-v\"); err != nil {\n\t\t\treturn \"\", 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)\n\t\t} else if len(remotes) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"failed to clone repo %s: remote not set for existing clone\", g.Repo)\n\t\t}\n\n\t\t// if sync property is false, then skip fetching latest from remote and resetting the branch.\n\t\tif g.Sync != nil && !*g.Sync {\n\t\t\treturn repoCacheDir, nil\n\t\t}\n\n\t\t// if sync is turned off via flag `--sync-remote-cache`, then skip fetching latest from remote and resetting the branch.\n\t\tif opts.SyncRemoteCache.FetchDisabled() {\n\t\t\treturn repoCacheDir, nil\n\t\t}\n\n\t\ttryUpdateRemoteOriginFetchURL(ctx, r, g.RepoCloneURI)\n\n\t\tif _, err = r.Run(ctx, \"fetch\", \"origin\", ref); err != nil {\n\t\t\treturn \"\", 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)","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/git/gitutil.go#L131-L167","documentation":"Thrown by syncRepo when an existing cached clone is present but `git remote -v` fails inside it. syncRepo treats this as a corrupted or inaccessible cache clone and suggests verifying credentials, because usually the cache dir is unreadable or git can't operate there (dubious ownership, permissions, or corruption).","triggerScenarios":"repoCacheDir already exists (os.Stat succeeded) and `git remote -v` run with Dir=repoCacheDir returns a non-zero exit: not a git repo, permission denied, or git 'dubious ownership' safe.directory rejection.","commonSituations":"Cache dir populated by a different user (CI ran as root, dev runs as user) triggering git's safe.directory error; partial cache dir missing .git; cache dir on a volume that lost permissions; skaffold cache mounted read-only.","solutions":["Clear the cache: rm -rf <remote-cache-dir>/<hash> and let skaffold re-clone from scratch.","If it's a git ownership issue, either chown the dir to the current user or add `git config --global --add safe.directory <path>`.","Fix directory permissions so the current user can read .git inside the cached clone.","Ensure the cache volume is mounted read-write wherever skaffold runs."],"exampleFix":"// before\n# cache owned by root, running as user -> git refuses\n// after\nsudo chown -R $(whoami) ~/.skaffold/gitcache\n# or\ngit config --global --add safe.directory '*'","handlingStrategy":"retry","validationCode":"const { execSync } = require('child_process');\nfunction cachedCloneUsable(dir) {\n  try {\n    const out = execSync(`git -C ${dir} remote -v`, { encoding: 'utf8' });\n    return out.trim().length > 0;\n  } catch (e) {\n    // typical fix: dubious ownership\n    execSync(`git config --global --add safe.directory ${dir}`, { stdio: 'pipe' });\n    try { return execSync(`git -C ${dir} remote -v`, { encoding: 'utf8' }).trim().length > 0; }\n    catch { return false; }\n  }\n}","typeGuard":"null","tryCatchPattern":"try {\n  await syncRepo(g, ctx, opts);\n} catch (err) {\n  if (/trouble checking repository remote/.test(err.message)) {\n    // nuke corrupted cache entry and retry fresh\n    fs.rmSync(path.join(cacheDir, hashFor(g)), { recursive: true, force: true });\n    return syncRepo(g, ctx, opts);\n  }\n  throw err;\n}","preventionTips":["Run all jobs (CI and local) under a consistent user so the cache isn't owned by root while used by a non-root user.","Add git safe.directory entries for shared cache paths.","Mount the cache volume read-write everywhere skaffold runs.","If you see this, prefer deleting the cache entry over repairing it."],"tags":["git","cache","permissions"],"backgroundTag":"git-dubious-ownership","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}