Skip to main content
DevOps Insightsguides & answers

Git · troubleshooting

fatal: detected dubious ownership in repository

Git refuses to work in a repository owned by another user, because that user's config could run commands as you. Common in containers, CI and shared drives. Fix the ownership, or mark that one path safe in your global config; a setting inside the repository is ignored.

Reproduced on Git 2.50.1, . Where the text says “reproduced”, the behaviour was run on that version, not taken from documentation.

First published

New to this? Read what is actually happening first, then come back to the steps.

On this page · 10 sections

Before you start

  • A shell in the place where git fails: the container, the CI step or the machine.
  • Permission to change file ownership (sudo) or to edit your own ~/.gitconfig.

Run this first

step 1 of 2
git rev-parse --show-toplevel 2>&1 | head -1

Look for The path to add, or to fix the ownership of

Repeats the error with the exact path Git checked.

Work out which cause you have

A few questions to narrow the list. Every answer ends in a command that confirms or rules the cause out — this cannot see your cluster, so nothing here is a certainty until you have checked.

Narrow it down

0 answered · nothing is sent anywhere

Where does git fail?

Cause space

3 of 3 still possible

  • A container sees files owned by another user IDCommon
  • CI clones as one user and runs git as anotherCommon
  • A shared directory, network drive or WSL mountOccasional

Nothing ruled out yet. Answer the question above and the branches your answer eliminates will strike through here.

Check it with a tool

Or diagnose it manually

In this order. The first command usually contains the whole answer.

  1. Step 1

    git rev-parse --show-toplevel 2>&1 | head -1

    Repeats the error with the exact path Git checked.

    Look for The path to add, or to fix the ownership of

  2. Step 2

    git config --show-origin --get-all safe.directory

    Lists every safe.directory entry and which config file it comes from.

    Look for Entries from file:.git/config are ignored; only system and global count

Every cause, and how to fix it

Ordered by how often each one turns out to be the answer.

A container sees files owned by another user ID

Common

The repository was cloned on the host, or by a CI step, as one user, and is mounted into a container that runs git as root or a different user. The owner IDs differ, so Git refuses.

Confirm

stat -c '%u %U' .
id -u

Two different numbers: the directory's owner and you. (On macOS: stat -f '%u %Su' .)

Fix

  • Run the container as the owner of the files: docker run --user "$(id -u):$(id -g)" … so they match.
  • Or mark the mounted path safe inside the container, for that one path: git config --global --add safe.directory /workspace/repo (or git -c safe.directory=/workspace/repo … for a single command).
  • In a Dockerfile that builds from a copied repository, chown the files to the build user, or add the path to safe.directory in the image's global config.
git config --global --add safe.directory /workspace/repo

Use the exact path from the error. Per command instead: git -c safe.directory=/workspace/repo status

CI clones as one user and runs git as another

Common

The checkout step ran as one user and wrote safe.directory into that user's global config; a later step runs as root, as another user or in its own container, with a different global config that has no entry.

Confirm

id -un; git config --global --get-all safe.directory

No entry for the workspace path for the user running the failing step

Fix

  • Add the workspace path in the step that fails, as the user it runs as: git config --global --add safe.directory "$GITHUB_WORKSPACE".
  • For a docker run step, pass it into the container per command: git -c safe.directory=/github/workspace ….

A shared directory, network drive or WSL mount

Occasional

A repository on a shared path created by a colleague, on a network share, or on a Windows drive accessed from WSL, where files show an owner that is not your Linux user.

Confirm

ls -ld .git

An owner other than you

Fix

  • If the files should be yours, take ownership: sudo chown -R "$USER" /path/to/repo.
  • If they are genuinely shared and you trust everyone who can write there, add that path, or PARENT/* with Git 2.46 or later, to your global safe.directory.

Understanding it properly

Skip this if you are mid-incident — the working part of the page is above. Worth reading afterwards, because understanding the mechanism is what stops the next one.

In plain terms

A repository's settings can tell Git to run programs, for example hooks or a custom pager. If someone else owns a repository on your machine and you run git there, their settings would run as you. Since 2022 Git checks who owns the repository and stops if it is not you. That is the right call on a shared machine, and a nuisance in a container, where the files were simply created by a different user.

Words used on this page

safe.directory
A list in your global or system Git config of repositories you trust even though another user owns them.
Protected configuration
The system and global config files and the command line. Git reads safe.directory only from these, never from the repository itself.
CVE-2022-24765
The vulnerability the ownership check fixed: a repository created by another user could make your git commands run their code.
SUDO_UID
Set by sudo. Git running as root under sudo also trusts repositories owned by the user who ran sudo.
What is actually happening

Git compares the owner of the repository directory with the user running it. If they differ, Git refuses before reading the repository's config, prints the path, and suggests the safe.directory command. The check arrived in Git 2.35.2 and the security releases of April 2022 for CVE-2022-24765.

Only your system or global config, or the command line, can mark a repository safe. A safe.directory line in the repository's own .git/config is ignored, since that file is exactly what is not trusted. Reproduced on Git 2.50.1, with Git's own test switch (GIT_TEST_ASSUME_DIFFERENT_OWNER) standing in for a second user.

Containers are the usual trigger: a volume or bind mount keeps the host's owner ID, the container runs as root or another user, and Git sees someone else's repository. CI systems that clone as one user and build as another hit it too, as do Windows drives seen through WSL.

actions/checkout adds the workspace to safe.directory in the global config by default (set-safe-directory: true). A later step that runs git as another user, or inside its own docker run container, does not see that entry.

How to tell this is your problem
WhereWhat you see
Any git commandfatal: detected dubious ownership in repository at '/workspace/repo' To add an exception for this directory, call: git config --global --add safe.directory /workspace/repo
Build tools that call gitA version stamp, git describe or a Go build failing with the same message wrapped in its own error

How to know it is actually fixed

  • git status works in the repository.
  • git config --show-origin --get-all safe.directory shows the entry in your global (or system) file, not a wildcard you did not mean.

Stopping it happening again

  • Run containers that touch a mounted repository as the same user ID as the files.
  • In CI, keep checkout and later git steps under one user, or add the workspace path in each step that changes user.
  • Avoid safe.directory = * outside throwaway containers.

Security considerations

  • safe.directory = * switches the check off for every repository, including one another user plants in a shared directory. Prefer the exact path, or a PARENT/* that only you write to.
  • Changing ownership with chown -R is the cleanest fix when the files should be yours; marking a repository safe is for when they genuinely belong to someone else.

Sources

Behaviour described here is drawn from official documentation. Where a figure could not be confirmed on an official page it is attributed in the text rather than stated as canonical.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it