AVC denial

SELinux Denied Operation: Fix the AVC Denial Fast

Linux & Unix Intermediate 👁 15 views 📅 Jun 18, 2026

SELinux blocking an operation? We'll find the denial in audit.log, fix the context or policy, and prevent it from coming back.

Quick answer

Run sudo ausearch -m avc -ts recent | audit2why to see the denial reason, then either restorecon -v /path to fix a label, or setsebool -P boolean_name on to enable a policy boolean.

What’s happening?

SELinux enforces a mandatory access control policy on every process and file. When something gets denied, it’s usually because the file has the wrong security context (label) or the policy doesn’t allow that operation by default. I’ve seen this mostly when you copy files from a non-SELinux system (like a Docker container or a backup) — the files inherit the wrong context, or when a new service tries to bind to a high port that’s restricted. The error message you see in dmesg or /var/log/messages will say something like “SELinux is preventing httpd from open access on the file /var/www/html/index.html.” It’s frustrating, but the fix is straightforward once you know where to look.

I’ll walk you through the standard fix that works on RHEL 8/9, CentOS Stream 9, Fedora 38+, and Rocky Linux 9. If you’re on an older version like RHEL 7, the commands are the same — just make sure policycoreutils and setroubleshoot are installed.

Step-by-step fix

  1. Install setroubleshoot if missing. This gives you sealert, which translates AVC denials into plain English. On RHEL/Fedora: sudo dnf install setroubleshoot setroubleshoot-server. On Debian/Ubuntu it’s rarely used — SELinux is enforcing by default only on CentOS/RHEL-family.
  2. Check the denial in real time. Run sudo tail -f /var/log/audit/audit.log | grep AVC. Then trigger the operation that failed (e.g., restart the service or access the file). You’ll see lines like type=AVC msg=audit(1234567890.123:456): avc: denied { write } for pid=1234 comm="httpd" name="index.html" dev="dm-0" ino=789 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file.
  3. Interpret the denial. The key parts: scontext (source context — the process, here httpd_t), tcontext (target context — the file or resource, here user_home_t), and tclass (file, dir, port, etc.). The denial is “httpd_t trying to write to a file labeled user_home_t.” That’s a label mismatch.
  4. Fix the label. If the file should be served by Apache, relabel it: sudo restorecon -v /var/www/html/index.html. If it’s a whole directory: sudo restorecon -R /var/www/html. If the file doesn’t have a default context, set one: sudo semanage fcontext -a -t httpd_sys_content_t '/var/www/html(/.*)?' then restorecon -R /var/www/html. Note: restorecon reads the file contexts defined by semanage — if you haven’t set one, it won’t change anything.
  5. If it’s a boolean. Some denials are expected and controlled by SELinux booleans. Example: Apache writing to user home directories. Instead of relabeling, toggle the boolean: sudo setsebool -P httpd_enable_homedirs on. To find the right boolean, run sudo sealert -a /var/log/audit/audit.log — it will suggest the boolean name.
  6. If it’s a port. Binding to a non-standard port? sudo semanage port -a -t http_port_t -p tcp 8080 to add it.
  7. Test the fix. Retry the operation. If it works, you’re done. If not, check audit.log again — sometimes one denial hides another.

Alternative fixes if the main one fails

Method 1: Disable SELinux temporarily — only as a test. sudo setenforce 0. If the operation works now, it’s definitely SELinux. Run setenforce 1 to re-enable. Never leave it disabled in production.

Method 2: Use audit2allow to create a custom policy module. This is for rare cases where no boolean or label fix exists. Example: sudo grep AVC /var/log/audit/audit.log | audit2allow -M mycustommodule then sudo semodule -i mycustommodule.pp. But be careful — this can create a permissive rule. I’ve seen people use this as a crutch instead of fixing the actual label.

Method 3: Check if the file is on a filesystem mounted with context= or no context. If you mount an NFS or tmpfs without context=, files get a generic label. Add context=system_u:object_r:httpd_sys_content_t:s0 to the mount options in /etc/fstab and remount.

Prevention tip

Use semanage fcontext to set permanent file contexts before deploying files. For example, if you have a custom web app directory at /opt/myapp, run semanage fcontext -a -t httpd_sys_content_t '/opt/myapp(/.*)?' and then restorecon -R /opt/myapp. This way, even if you copy files again, the restorecon command will reapply the correct label. Also, enable setroubleshoot and route its alerts to your logging system — it’ll email you on denials. I set that up on every server I manage; it catches issues before users do.

Was this solution helpful?