How to fix error: git operation blocked by AppArmor policy in Git

GitINTERMEDIATEMEDIUMUpdated Dec 6, 2025· 140 views

This Linux error occurs when AppArmor, a mandatory access control security system, blocks Git from performing operations such as cloning, pushing, or accessing files. AppArmor profiles restrict what resources applications can access, and a misconfigured or overly restrictive profile can prevent Git from functioning properly.

Quick fix

Fixes EACCES

# Check dmesg for AppArmor messages
sudo dmesg | grep -i apparmor | tail -20

# Check system log for audit messages
sudo grep "apparmor.*DENIED" /var/log/syslog | tail -20

# Or use journalctl (systemd systems)
sudo journalctl -k | grep -i apparmor | tail -20

# Stream live AppArmor denials
sudo dmesg -w | grep apparmor
  1. Identify the AppArmor denial in system logs
  2. Check AppArmor status and loaded profiles
  3. Set the problematic profile to complain mode (temporary fix)
  4. Fix snap-installed Git access issues
git — error
# Check dmesg for AppArmor messages
sudo dmesg | grep -i apparmor | tail -20
# Check system log for audit messages
sudo grep "apparmor.*DENIED" /var/log/syslog | tail -20
# Or use journalctl (systemd systems)
sudo journalctl -k | grep -i apparmor | tail -20
# Stream live AppArmor denials
sudo dmesg -w | grep apparmor
error: git operation blocked by AppArmor policy

What this error means

This error indicates that the Linux AppArmor security module is preventing Git from executing operations it needs to perform. AppArmor (Application Armor) is a Mandatory Access Control (MAC) security system that confines programs to a limited set of resources using per-program profiles. When Git is blocked by AppArmor, it means the security policy explicitly denies Git (or the process running Git) from accessing certain files, directories, network resources, or system capabilities. This commonly happens in the following scenarios: 1. **Snap-packaged Git**: When Git is installed as a snap package, it runs under AppArmor confinement that may restrict access to directories outside the snap sandbox. 2. **Container environments**: Git running inside LXD, Docker containers, or other containerized environments where AppArmor profiles are enforced. 3. **Custom AppArmor profiles**: System administrators may have deployed restrictive AppArmor profiles that inadvertently block Git operations. 4. **Ubuntu 23.10+ user namespace restrictions**: Starting with Ubuntu 23.10, AppArmor restricts unprivileged user namespace creation, which can affect Git operations that rely on namespace isolation. The AppArmor denial is logged in the system log with a message like: ``` audit: apparmor="DENIED" operation="open" profile="snap.git.git" name="/path/to/file" ``` Understanding whether Git itself is confined or whether the parent process (terminal, IDE, snap runtime) is confined is crucial for resolving this issue.

Typical symptoms

  • Git commands fail with 'Permission denied' errors despite correct file permissions
  • Git works when run as root but fails as a regular user
  • System log shows 'apparmor="DENIED"' entries when running Git
  • Git clone or pull fails when accessing specific directories
  • Snap-installed Git cannot access files outside home directory
  • Git operations fail inside LXD or Docker containers on AppArmor-enabled hosts
  • Git hooks fail with permission errors in confined environments
  • IDE Git integration fails while terminal Git works (or vice versa)
  • Git submodule operations fail with access denied errors
  • 'Operation not permitted' errors when Git tries to create files

Common causes

  1. Git installed as a snap package with strict confinement limiting file access
  2. AppArmor profile blocking Git from accessing directories outside allowed paths
  3. Running Git in a container where host AppArmor profiles are enforced
  4. Ubuntu 23.10+ user namespace restrictions affecting Git operations
  5. Custom or third-party AppArmor profiles with overly restrictive rules
  6. AppArmor profile not updated after Git or system upgrade
  7. Corrupted or misconfigured AppArmor profile for snap.git or related applications
  8. Terminal emulator or IDE running under restrictive AppArmor confinement
  9. Network operations blocked by AppArmor network access rules
  10. SELinux or other security modules conflicting with AppArmor configuration

How to fix "error: git operation blocked by AppArmor policy"

1Identify the AppArmor denial in system logs

First, check the system logs to understand exactly what AppArmor is denying:

View recent AppArmor denials:

bash
# Check dmesg for AppArmor messages
sudo dmesg | grep -i apparmor | tail -20

# Check system log for audit messages
sudo grep "apparmor.*DENIED" /var/log/syslog | tail -20

# Or use journalctl (systemd systems)
sudo journalctl -k | grep -i apparmor | tail -20

# Stream live AppArmor denials
sudo dmesg -w | grep apparmor

Understand the denial message:
A typical AppArmor denial looks like:

bash
audit: apparmor="DENIED" operation="open" profile="snap.git.git" name="/home/user/project/.git/config" pid=12345 comm="git" requested_mask="r" denied_mask="r"

Key fields to examine:
- profile: Which AppArmor profile is enforcing the denial (e.g., snap.git.git)
- operation: What operation was blocked (open, read, write, exec, etc.)
- name: The file or resource being accessed
- requested_mask: What access was requested (r=read, w=write, x=execute)
- denied_mask: What access was denied

This information is essential for determining the correct fix.

2Check AppArmor status and loaded profiles

Determine which AppArmor profiles are active and their enforcement mode:

Check overall AppArmor status:

bash
# View AppArmor status (requires root)
sudo aa-status

# Sample output:
# apparmor module is loaded.
# 47 profiles are loaded.
# 45 profiles are in enforce mode.
# 2 profiles are in complain mode.
# 10 processes have profiles defined.

Look for Git-related profiles:

bash
# List all loaded profiles
sudo aa-status | grep -i git

# Check for snap Git profiles
ls -la /var/lib/snapd/apparmor/profiles/ | grep git

# Check system AppArmor profiles
ls -la /etc/apparmor.d/ | grep -i git

Check if Git is running under a profile:

bash
# Find Git process and its profile
ps auxZ | grep git

# Or check which profile is confining a process
sudo aa-status --json | jq '.processes'

Install AppArmor utilities if missing:

bash
# Ubuntu/Debian
sudo apt install apparmor-utils

# Arch Linux
sudo pacman -S apparmor

This step helps identify whether Git itself has a profile or if the issue is with a parent process profile.

3Set the problematic profile to complain mode (temporary fix)

For immediate relief, switch the blocking profile to complain mode, which logs violations without blocking them:

Put a profile in complain mode:

bash
# For system profiles
sudo aa-complain /etc/apparmor.d/profile.name

# For snap profiles (use the profile name from aa-status)
sudo aa-complain snap.git.git

# Or directly reference the profile file
sudo aa-complain /var/lib/snapd/apparmor/profiles/snap.git.git

Verify the profile is now in complain mode:

bash
sudo aa-status | grep -A5 "complain mode"

Test Git operations:

bash
# Try the previously failing command
git status
git pull

Important notes:
- Complain mode is for troubleshooting only; it reduces security
- Use this to confirm AppArmor is the cause before making permanent fixes
- Switch back to enforce mode once you've identified and fixed the root cause:

bash
# Return to enforce mode
sudo aa-enforce /etc/apparmor.d/profile.name

If Git works in complain mode, you've confirmed AppArmor is the issue.

4Fix snap-installed Git access issues

If Git is installed via snap, it has strict confinement that limits file access:

Check if Git is a snap:

bash
which git
# If output is /snap/bin/git, it's a snap package

snap list git

Option 1: Connect required interfaces

bash
# List available interfaces
snap connections git

# Connect to removable-media for access to /media, /mnt, etc.
sudo snap connect git:removable-media

# Connect to home for full home directory access
sudo snap connect git:home

Option 2: Use classic Git from apt instead of snap

bash
# Remove snap Git
sudo snap remove git

# Install Git from apt (not confined)
sudo apt install git

# Verify installation
which git  # Should show /usr/bin/git

Option 3: Debug snap AppArmor denials

bash
# Install the snap debugging tool
sudo snap install snappy-debug

# Run the debug scanner
sudo snappy-debug.security scanlog

# In another terminal, run the failing Git command
git clone https://github.com/user/repo.git /path/to/destination

The snappy-debug tool will suggest which interfaces or manual profile modifications might be needed.

Reload snap AppArmor profiles:

bash
sudo apparmor_parser -r /var/lib/snapd/apparmor/profiles/*
sudo systemctl restart snapd.apparmor.service
5Fix container-related AppArmor issues

If Git fails inside LXD, Docker, or other containers due to AppArmor:

For LXD containers:

bash
# Check container security settings
lxc config show mycontainer | grep apparmor

# Disable AppArmor for the container (reduces security)
lxc config set mycontainer raw.lxc "lxc.apparmor.profile=unconfined"
lxc restart mycontainer

# Or use a specific AppArmor profile
lxc config set mycontainer raw.lxc "lxc.apparmor.profile=lxc-container-default-with-nesting"

For Docker containers:

bash
# Run container with AppArmor disabled (reduces security)
docker run --security-opt apparmor=unconfined myimage

# Or in docker-compose.yml:
# services:
#   myservice:
#     security_opt:
#       - apparmor:unconfined

Fix host-level Docker AppArmor issues:

bash
# Reload Docker's default AppArmor profile
sudo apparmor_parser -r /etc/apparmor.d/docker

# Or remove and re-add the profile
sudo apparmor_parser -R /etc/apparmor.d/docker
sudo apparmor_parser -a /etc/apparmor.d/docker

Check for nested container issues:

bash
# View AppArmor denials from container perspective
dmesg | grep apparmor

# Ensure nesting is enabled if running containers inside containers
lxc config set mycontainer security.nesting true
6Address Ubuntu 23.10+ user namespace restrictions

Starting with Ubuntu 23.10, AppArmor restricts unprivileged user namespace creation, which can affect some Git operations:

Check if this restriction is affecting you:

bash
# Look for userns_create denials
dmesg | grep "userns_create"

# Check the kernel settings
sysctl kernel.apparmor_restrict_unprivileged_userns
sysctl kernel.apparmor_restrict_unprivileged_unconfined

Temporary workaround (testing only):

bash
# Disable user namespace restrictions temporarily
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
sudo sysctl -w kernel.apparmor_restrict_unprivileged_unconfined=0

Permanent workaround (if needed):

bash
# Create a sysctl configuration file
echo "kernel.apparmor_restrict_unprivileged_userns=0" | sudo tee /etc/sysctl.d/99-userns.conf
sudo sysctl --system

Better approach - create an AppArmor profile for Git:

bash
# Check if a profile already exists
ls /etc/apparmor.d/ | grep git

# If Git needs user namespace access, create a permissive profile
# (This is an advanced operation - see Advanced Notes)

Note: Disabling user namespace restrictions reduces system security. Only do this if you understand the implications and have other security measures in place.

7Modify or create a custom AppArmor profile for Git

If you need to create or modify an AppArmor profile to allow specific Git operations:

Locate existing profiles:

bash
# System profiles
ls /etc/apparmor.d/

# Local overrides (preferred for modifications)
ls /etc/apparmor.d/local/

# Snap profiles
ls /var/lib/snapd/apparmor/profiles/

Use aa-logprof to suggest profile updates:

bash
# Run the failing Git command first, then:
sudo aa-logprof

# This interactive tool will scan logs and suggest profile additions

Manually add rules to local overrides:

bash
# Create or edit a local override file
sudo nano /etc/apparmor.d/local/usr.bin.git

Example rules to add:

bash
# Allow Git to read/write in home directory
owner @{HOME}/** rw,

# Allow Git to access .git directories anywhere
/**/.git/ r,
/**/.git/** rwk,

# Allow network access for remote operations
network inet stream,
network inet6 stream,

# Allow Git to execute helper programs
/usr/lib/git-core/* ix,
/usr/bin/ssh ix,

Reload the profile after changes:

bash
# Reload specific profile
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.git

# Or reload all profiles
sudo systemctl reload apparmor

Test the updated profile:

bash
# Run Git command and check for denials
git status
dmesg | tail -5 | grep apparmor
8Disable AppArmor profile for Git (not recommended)

As a last resort, you can disable AppArmor protection for Git entirely:

Disable a specific profile:

bash
# Create a symlink to disable the profile
sudo ln -s /etc/apparmor.d/profile.name /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/profile.name

# For example, if there's a Git profile:
sudo ln -s /etc/apparmor.d/usr.bin.git /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.bin.git

Re-enable a disabled profile:

bash
sudo rm /etc/apparmor.d/disable/profile.name
sudo apparmor_parser -a /etc/apparmor.d/profile.name

Disable AppArmor system-wide (strongly not recommended):

bash
# Via kernel parameter
sudo nano /etc/default/grub
# Change: GRUB_CMDLINE_LINUX=""
# To: GRUB_CMDLINE_LINUX="apparmor=0"
sudo update-grub
sudo reboot

# Or via systemd
sudo systemctl stop apparmor
sudo systemctl disable apparmor

Warning: Disabling AppArmor removes an important security layer. Only disable profiles or the entire system if:
- You are in a development/testing environment
- You have alternative security measures in place
- You fully understand the security implications

Prefer using complain mode or creating permissive profiles over complete disabling.

9Verify the fix and test Git operations

After applying fixes, thoroughly test Git functionality:

Test basic operations:

bash
# Navigate to your repository
cd /path/to/repo

# Test status
git status

# Test log
git log --oneline -5

# Test diff
git diff HEAD~1

Test network operations:

bash
# Test fetch
git fetch origin

# Test pull
git pull

# Test clone to a new location
git clone https://github.com/octocat/Hello-World.git /tmp/test-clone
rm -rf /tmp/test-clone

Test write operations:

bash
# Create a test file and commit
echo "test" > test-apparmor.txt
git add test-apparmor.txt
git commit -m "Test AppArmor fix"
git reset --hard HEAD~1  # Undo test commit

Verify no new denials appear:

bash
# Check dmesg for any new AppArmor denials
sudo dmesg | grep apparmor | tail -10

# Monitor in real-time during operations
sudo dmesg -w | grep apparmor &
git pull
# Press Ctrl+C to stop monitoring

Test in previously problematic contexts:
If the issue was specific to an IDE or container, test Git within that context as well.

If issues persist:

bash
# Generate a full AppArmor report
sudo aa-status --verbose > apparmor-report.txt
sudo dmesg | grep apparmor >> apparmor-report.txt
# Review the report or share with support

Advanced notes

### Understanding AppArmor Architecture

AppArmor is a Linux Security Module (LSM) that provides Mandatory Access Control (MAC). Unlike traditional UNIX Discretionary Access Control (DAC) where file owners set permissions, MAC policies are enforced by the system administrator and cannot be overridden by users.

Key concepts:

1. Profiles: Text files defining what resources a program can access
2. Modes:
- Enforce: Violations are blocked and logged
- Complain: Violations are logged but allowed
- Disabled: Profile is not loaded
3. Capabilities: POSIX capabilities the program can use (e.g., CAP_NET_BIND_SERVICE)
4. File rules: Path-based access controls (read, write, execute, etc.)
5. Network rules: Network family and socket type restrictions

### Profile Syntax Basics

AppArmor profiles use a C-like syntax:

bash
# Example profile structure
/usr/bin/git {
  # Include common abstractions
  #include <abstractions/base>
  #include <abstractions/nameservice>

  # Allow reading Git configuration
  /etc/gitconfig r,
  owner @{HOME}/.gitconfig r,

  # Allow access to .git directories
  /**/.git/ r,
  /**/.git/** rwk,

  # Allow executing Git helpers
  /usr/lib/git-core/* ix,

  # Network access for remotes
  network inet stream,
  network inet6 stream,

  # Allow DNS resolution
  /etc/resolv.conf r,
}

Common file access modes:
- r - read
- w - write
- a - append
- x - execute (inherit profile)
- ix - execute inheriting current profile
- px - execute with dedicated profile
- ux - execute unconfined
- k - file locking
- l - link

### Snap Confinement Levels

Snap packages have three confinement levels:

1. strict (default): Full AppArmor and seccomp confinement
2. classic: No confinement (like apt packages)
3. devmode: Confinement disabled for development

bash
# Check snap confinement level
snap info git | grep confinement

# Install a snap in classic mode (if available)
sudo snap install git --classic

# Install in devmode (for debugging)
sudo snap install git --devmode

### Debugging with aa-logprof and aa-genprof

For creating or updating profiles:

bash
# Generate a new profile interactively
sudo aa-genprof /usr/bin/git
# Then run Git commands in another terminal
# Return and press 'S' to scan, 'F' to finish

# Update existing profile based on log
sudo aa-logprof

The tool will suggest rules based on observed denials.

### Network-Specific AppArmor Rules

If Git is being blocked from network operations:

bash
# Allow all TCP connections
network inet stream,
network inet6 stream,

# Allow DNS
network inet dgram,
network inet6 dgram,

# Allow Unix sockets (for credential helpers)
network unix stream,

### Troubleshooting SSH with Git and AppArmor

If SSH-based Git operations fail:

bash
# Check if SSH is confined
ps auxZ | grep ssh

# SSH might need its own profile adjustments
# Check for SSH-related denials
dmesg | grep -E "apparmor.*ssh"

Rules to add for SSH support:

bash
/usr/bin/ssh ix,
owner @{HOME}/.ssh/** r,
owner @{HOME}/.ssh/known_hosts rw,

### AppArmor vs SELinux

Some systems may have SELinux instead of (or in addition to) AppArmor:

bash
# Check which LSM is active
cat /sys/kernel/security/lsm

# Check SELinux status
getenforce  # If SELinux

# Check AppArmor status
aa-status  # If AppArmor

If both are present, ensure they're not conflicting.

### Kernel Parameters for AppArmor

bash
# View all AppArmor kernel parameters
sysctl -a | grep apparmor

# Key parameters:
# kernel.apparmor_restrict_unprivileged_userns - User namespace restrictions
# kernel.apparmor_restrict_unprivileged_unconfined - Unconfined process restrictions

### Recovery from AppArmor Issues

If AppArmor completely breaks your system:

1. Boot with AppArmor disabled:
- At GRUB menu, press 'e' to edit
- Add apparmor=0 to the linux line
- Press Ctrl+X to boot

2. Fix the problematic profile:

bash
# Once booted, fix or remove the profile
   sudo rm /etc/apparmor.d/broken.profile
   sudo systemctl restart apparmor

3. Reboot normally

### Enterprise Considerations

In managed environments:
- AppArmor profiles may be deployed via configuration management
- Contact your security team before modifying profiles
- Document any profile changes for audit purposes
- Consider using complain mode in staging before enforce in production

Frequently asked questions

What does "EACCES" mean?
This error indicates that the Linux AppArmor security module is preventing Git from executing operations it needs to perform. AppArmor (Application Armor) is a Mandatory Access Control (MAC) security system that confines programs to a limited set of resources using per-program profiles. When Git is blocked by AppArmor, it means the security policy explicitly denies Git (or the process running Git) from accessing certain files, directories, network resources, or system capabilities.
How do I fix "EACCES"?
This Linux error occurs when AppArmor, a mandatory access control security system, blocks Git from performing operations such as cloning, pushing, or accessing files. AppArmor profiles restrict what resources applications can access, and a misconfigured or overly restrictive profile can prevent Git from functioning properly.
What causes "EACCES"?
Git installed as a snap package with strict confinement limiting file access AppArmor profile blocking Git from accessing directories outside allowed paths Running Git in a container where host AppArmor profiles are enforced
Is the "EACCES" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading