When SELinux blocks something and you need to debug, use permissive mode, not disabled. Permissive logs what would have been denied and keeps labeling files correctly. Disabled loads no policy, logs nothing and leaves new files unlabeled, which makes a later switch back to enforcing painful.
Check what you have
Run getenforce. It prints Enforcing, Permissive or Disabled. For more detail run sestatus, which also shows the loaded policy, the current mode and the mode set in the config file. If those last two differ, someone changed the mode at runtime and it will revert at the next boot.
What each state does
Red Hat's documentation for RHEL 9 describes the three states plainly.
- Enforcing: the policy is applied and access is denied based on its rules. On RHEL this is the default when the system was installed with SELinux.
- Permissive: the policy is not enforced. Nothing is denied. SELinux only logs AVC messages, which you can use for troubleshooting and policy improvements.
- Disabled: no policy is loaded, nothing is enforced and AVC messages are not logged. The documentation says all benefits of running SELinux are lost.
The guide says not to disable SELinux except in specific cases, such as performance sensitive systems where the weaker security does not pose significant risk. It also says that to debug in production, use permissive mode temporarily instead of disabling.
Why disabled makes later work harder
SELinux depends on correct labels on files. The documentation warns that while disabled, new file system objects are not labeled at all, and in permissive mode users and processes may label some objects incorrectly. Switching back to enforcing then causes failures, because the labels are missing or wrong.
That is why moving from disabled to enabled triggers a relabel of the file systems on the next boot.
Quirks of permissive logging
Permissive logs differently from enforcing. The documentation notes that in permissive mode only the first denial in a series of the same denials is reported. In enforcing mode an application may stop at the first denial, while in permissive mode it continues and you see a denial for each later access. So the permissive log can show more events than the enforcing failure suggested, which is useful when you want the full list.
A safe debugging routine
- Note the current mode with
getenforce. - Switch to permissive for the shortest time you can.
setenforce 0changes the mode until reboot. SettingSELINUX=permissivein/etc/selinux/configmakes it persistent, which you rarely want. - Reproduce the problem and read the denials. As root,
ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts todaylists them. - Fix the label, boolean or policy module the log points to.
- Switch back to enforcing and test again.
- Record what you changed.
Adding a one-line change to an allow rule without understanding the denial is how holes get created. Fix the cause, which is usually a mislabeled path or a missing boolean.
If you run AppArmor instead, the same complain versus enforce idea applies.
Safeguard can sit alongside host hardening: policies and gates in the pipeline, SBOM and dependency scanning, and a free scan at gold.safeguard.sh/scan.
Quick check
Does permissive mode block anything?
No. It only logs what the policy would have denied.
Why not just set SELinux to disabled while I debug?
Files created while disabled are not labeled, and no denials are logged. Re-enabling needs a relabel and can cause boot or service problems.
Sources
Last reviewed: 19 October 2026.