The 'unsafe repository' error occurs when Git detects that the repository is owned by a different user than the one running Git commands. This security feature was introduced in Git 2.35.2 to prevent CVE-2022-24765, which could allow malicious code execution.
This error is a security feature introduced in Git 2.35.2 (April 2022) to protect against CVE-2022-24765, a vulnerability that could allow malicious actors to execute arbitrary commands through specially crafted Git repositories. When you run a Git command, Git searches for a `.git` directory starting from the current directory and moving upward through parent directories. Before this security fix, an attacker with write access to a shared machine could create a malicious `.git` directory in a common location (like `C:\` on Windows or `/tmp` on Linux), causing Git to load malicious configuration when unsuspecting users ran Git commands. The security check compares the ownership of the directory containing the `.git` folder against the user executing Git commands. If they don't match, Git refuses to operate on the repository and displays this "unsafe repository" error. This commonly happens in legitimate scenarios: - Running commands in Docker containers where files are mounted from the host - Working with repositories on network shares or external drives - Using WSL (Windows Subsystem for Linux) with Windows-mounted directories - CI/CD pipelines running as different users than repository owners - sudo or administrative operations on repositories owned by regular users
The quickest fix is to explicitly tell Git to trust this specific repository:
# Add a single repository to safe.directory (recommended)
git config --global --add safe.directory /path/to/your/repo
# Example for a specific project
git config --global --add safe.directory /home/otheruser/projects/myrepo
# On Windows (use forward slashes or escaped backslashes)
git config --global --add safe.directory "C:/Users/OtherUser/projects/myrepo"
git config --global --add safe.directory "C:\\Users\\OtherUser\\projects\\myrepo"This adds an entry to your ~/.gitconfig file:
[safe]
directory = /path/to/your/repoNote: You need to run this command for each repository you want to trust, or use the wildcard option in the next step.
If you frequently work with repositories owned by other users and understand the security implications, you can trust all directories:
# Trust all repositories (less secure, but convenient)
git config --global --add safe.directory '*'Security Warning: This disables the ownership check entirely. Only use this on:
- Personal development machines where you're the only user
- Isolated Docker containers with no untrusted code
- Secure CI/CD environments
NOT recommended for:
- Shared servers or multi-user systems
- Production environments
- Systems where others can create directories
To remove this later:
git config --global --unset-all safe.directoryIf you own the machine and the repository should belong to you, fixing the ownership is the cleanest solution:
On Linux/macOS:
# Change ownership to current user
sudo chown -R "$USER":"$(id -gn)" /path/to/repo
# Or specify user explicitly
sudo chown -R username:groupname /path/to/repo
# Verify ownership
ls -la /path/to/repoOn Windows (Command Prompt as Administrator):
takeown /f "C:\path\to\repo" /r /d Y
icacls "C:\path\to\repo" /grant "%USERNAME%":F /TOn Windows (PowerShell as Administrator):
$path = "C:\path\to\repo"
$acl = Get-Acl $path
$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity, "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl.SetAccessRule($rule)
Set-Acl -Path $path -AclObject $aclDocker containers typically run as root or a specific user, while mounted volumes retain the host's file ownership. Here are several solutions:
Option 1: Add safe.directory in Dockerfile or entrypoint:
# In Dockerfile
RUN git config --global --add safe.directory /app
# Or for any directory
RUN git config --global --add safe.directory '*'Option 2: Set safe.directory via environment in docker-compose:
services:
app:
image: myapp
volumes:
- .:/app
environment:
- GIT_CONFIG_GLOBAL=/tmp/.gitconfig
command: >
sh -c "git config --global --add safe.directory /app && exec your-command"Option 3: Create .gitconfig before running container:
# Create config file on host
mkdir -p /home/runner/work/_temp/_github_home
printf "[safe]\n\tdirectory = /github/workspace" > /home/runner/work/_temp/_github_home/.gitconfig
# Mount it in container
docker run -v /home/runner/work/_temp/_github_home:/root .gitconfig:/.gitconfig myimageOption 4: Match container user to host user:
# Run container as current user
docker run --user "$(id -u):$(id -g)" -v "$PWD:/app" myimageGitHub Actions and other CI systems often encounter this when using custom Docker containers or specific checkout configurations.
For GitHub Actions:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4 # Use latest version
- name: Configure Git safe directory
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
# Your build steps...For Docker-based GitHub Actions:
jobs:
build:
runs-on: ubuntu-latest
container:
image: node:18
steps:
- name: Configure Git
run: |
git config --global --add safe.directory /github/workspace
git config --global --add safe.directory '*'
- name: Checkout
uses: actions/checkout@v4For GitLab CI:
before_script:
- git config --global --add safe.directory "$CI_PROJECT_DIR"For Jenkins:
pipeline {
agent any
stages {
stage('Configure Git') {
steps {
sh 'git config --global --add safe.directory "$WORKSPACE"'
}
}
}
}When accessing Windows filesystems from WSL, ownership appears as root, causing this error:
Option 1: Add specific directories to safe.directory:
# Add your Windows project directories
git config --global --add safe.directory /mnt/c/Users/YourName/Projects/myrepoOption 2: Configure mount options in /etc/wsl.conf:
# Create or edit /etc/wsl.conf
sudo nano /etc/wsl.confAdd these contents:
[automount]
enabled = true
options = "metadata,uid=1000,gid=1000,umask=022"Then restart WSL:
# In PowerShell (not WSL)
wsl --shutdownOption 3: Work within the Linux filesystem (recommended for performance):
# Clone repositories to Linux filesystem instead of /mnt/c
cd ~
git clone https://github.com/user/repo.git
# Linux filesystem paths start with /home, not /mnt
# This also improves Git performance significantlyAccess Linux files from Windows:
- In File Explorer: \\wsl$\Ubuntu\home\username\projects
- This approach avoids permission issues entirely
On shared systems where all users need access to specific repositories, configure at the system level:
# System-wide configuration (requires root/admin)
sudo git config --system --add safe.directory /shared/repo
# View system config location
git config --system --list --show-originTypical system config locations:
- Linux: /etc/gitconfig
- macOS: /usr/local/etc/gitconfig or $(brew --prefix)/etc/gitconfig
- Windows: C:\Program Files\Git\etc\gitconfig
Create a startup script for CI runners:
#!/bin/bash
# /etc/profile.d/git-safe.sh
git config --global --add safe.directory '*'Note: System-level configuration affects all users on the machine. Be cautious about disabling security checks system-wide.
After applying a fix, verify it's working:
# Check if repository is now accessible
git status
# List all safe.directory entries
git config --global --get-all safe.directory
# Show full configuration with file locations
git config --list --show-origin | grep safe
# Check who owns the repository
ls -la /path/to/repo
stat /path/to/repo
# Check current user
whoami
idIf still not working:
1. Check for multiple config files:
git config --list --show-origin2. Verify the exact path (no trailing slash):
# Wrong
git config --global --add safe.directory /path/to/repo/
# Correct
git config --global --add safe.directory /path/to/repo3. On Windows, try both path formats:
git config --global --add safe.directory "C:/path/to/repo"
git config --global --add safe.directory "C:\\path\\to\\repo"4. Remove and re-add:
git config --global --unset-all safe.directory
git config --global --add safe.directory /path/to/repo### Understanding CVE-2022-24765
This vulnerability allowed attackers to execute arbitrary commands when a user ran Git in a directory with a malicious .git folder created by another user. The attack vector:
1. Attacker creates /.git or C:\.git with malicious hooks or config
2. Victim runs git status in any subdirectory
3. Git traverses up, finds the malicious .git, and executes hooks
The safe.directory check prevents Git from using .git directories owned by other users.
### Alternative Workaround: GIT_CEILING_DIRECTORIES
Instead of safe.directory, you can limit how far Git searches upward:
# Prevent Git from searching above home directory
export GIT_CEILING_DIRECTORIES="$HOME"
# Or for Windows
export GIT_CEILING_DIRECTORIES="/c/Users/YourName"
# Add to shell profile (.bashrc, .zshrc)
echo 'export GIT_CEILING_DIRECTORIES="$HOME"' >> ~/.bashrc### Network Filesystems (NFS, SMB/CIFS)
Network mounts often cause ownership mismatches:
NFS with user mapping:
# In /etc/exports (server side)
/shared/repos client(rw,all_squash,anonuid=1000,anongid=1000)SMB/CIFS mount with uid/gid:
# In /etc/fstab
//server/share /mnt/share cifs uid=1000,gid=1000,credentials=/root/.smbcredentials 0 0### Git Version-Specific Behavior
- < 2.35.2: No ownership check
- 2.35.2+: Ownership check enabled, safe.directory introduced
- 2.36.0+: Better error messages and Windows path handling
- 2.38.0+: Improved WSL and Docker support
Check your version:
git --version### Downgrading Git (Not Recommended)
If you need to temporarily work around this on a secure, isolated system:
# Debian/Ubuntu - find available versions
apt-cache policy git
# Install specific older version (not recommended)
sudo apt install git=1:2.34.1-1ubuntu1Warning: Downgrading exposes you to CVE-2022-24765. Only do this temporarily on isolated systems.
### Dev Containers and VS Code
For VS Code Dev Containers, add to devcontainer.json:
{
"postCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}"
}Or in the Dockerfile:
RUN git config --system --add safe.directory '*'### Security Best Practices
1. Prefer changing ownership over adding to safe.directory
2. Use specific paths instead of wildcard *
3. Audit safe.directory entries periodically:
git config --global --get-all safe.directory4. Remove entries when no longer needed:
git config --global --unset safe.directory /old/path5. On shared systems, never use safe.directory = *
kex_exchange_identification: Connection closed by remote host
Connection closed by remote host when connecting to Git server
fatal: unable to access: Proxy auto-configuration failed
How to fix 'Proxy auto-configuration failed' in Git
fatal: unable to access: Authentication failed (proxy requires basic auth)
How to fix 'Authentication failed (proxy requires basic auth)' in Git
fatal: unable to access: no_proxy configuration not working
How to fix 'no_proxy configuration not working' in Git
fatal: unable to read tree object in treeless clone
How to fix 'unable to read tree object in treeless clone' in Git