Skip to content
Latchkey

Git "detected dubious ownership" - Add safe.directory in CI

When a checkout is owned by a different user than the one running Git, Git blocks it and tells you to add a safe.directory exception. This page is the focused recipe for setting that config correctly in CI.

What this error means

Git refuses to operate on the checkout and prints the safe.directory instruction. You need to add the exception so subsequent Git steps run - typically in container jobs or when a cache restored the repo as a different UID.

git output
fatal: detected dubious ownership in repository at '/__w/app/app'
To add an exception for this directory, call:
    git config --global --add safe.directory /__w/app/app

Diagnose it: depth, refs, or credentials?

CI checkouts are shallow and detached by default, which breaks anything that needs history or a branch name. Before treating it as a credential problem, confirm what the runner actually fetched.

.github/workflows/ci.yml
- run: |
    git rev-parse --is-shallow-repository
    git rev-parse --abbrev-ref HEAD      # prints HEAD when detached
    git log --oneline -3
    git remote -v
    git for-each-ref --format="%(refname)" | head

Common causes

Checkout UID differs from the Git process UID

A container step running as root over a workspace checked out by the runner user triggers Git’s ownership safety check.

Restored cache/artifact owned by another user

A cache or artifact unpacked the repo with a different owner, so the Git process now sees an untrusted directory.

How to fix it

Add the specific path as a safe directory

Trust the exact checkout path for the current user. Prefer the specific path over a wildcard.

Terminal
git config --global --add safe.directory /__w/app/app

Trust the workspace on an isolated runner

On an ephemeral, single-tenant runner you can trust all paths, but only there.

Terminal
git config --global --add safe.directory '*'

Set it via env for container steps

When you cannot run a config step first, pass the exception through the environment.

Terminal
export GIT_CONFIG_COUNT=1
export GIT_CONFIG_KEY_0=safe.directory
export GIT_CONFIG_VALUE_0=/__w/app/app

The checkout options that fix most of this

.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0        # full history: diffs, tags, git describe
    submodules: recursive # submodules are NOT fetched by default
    persist-credentials: false  # if a later step pushes with its own token

How to prevent it

  • Keep the checkout owner and the Git process user consistent.
  • Add safe.directory for the workspace in container-based jobs.
  • Avoid restoring caches/artifacts as a different UID into the repo path.

Frequently asked questions

What causes Git "detected dubious ownership"?
There are 2 common causes: checkout uid differs from the git process uid and restored cache/artifact owned by another user. A container step running as root over a workspace checked out by the runner user triggers Git’s ownership safety check.
How do I fix Git "detected dubious ownership"?
There are 3 fixes depending on which cause you have: add the specific path as a safe directory, trust the workspace on an isolated runner, and set it via env for container steps. Work through them in order, since the first is the most common.
What does Git "detected dubious ownership" actually mean?
Git refuses to operate on the checkout and prints the safe.directory instruction.
How do I stop Git "detected dubious ownership" happening again?
Keep the checkout owner and the Git process user consistent. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card