Skip to content

How to Fix Apache 403 Forbidden Error

DodaTech 2 min read

In this tutorial, you'll learn about How to Fix Apache 403 Forbidden Error. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Visiting your Apache-hosted site returns 403 Forbidden even though the files exist in the document root. Apache returns a 403 when the Require directive in the <Directory> block denies access, when the filesystem permissions prevent the www-data user from reading the files, or when Apache's SELinux context blocks access.

Quick Fix

1. Check filesystem permissions

ls -ld /var/www/html/
ls -l /var/www/html/index.html

Expected output:

drwxr-xr-x 2 www-data www-data 4096 Jan 15 10:30 /var/www/html/
-rw-r--r-- 1 www-data www-data  42 Jan 15 10:30 /var/www/html/index.html

Fix permissions if needed:

sudo chown -R www-data:www-data /var/www/html/
sudo chmod 755 /var/www/html/
sudo chmod 644 /var/www/html/index.html

2. Check the Directory directive in the virtual host

Open your site config:

sudo vim /etc/apache2/sites-available/000-default.conf

Ensure the <Directory> block has Require all granted:

<VirtualHost *:80>
    DocumentRoot /var/www/html

    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

3. Check the Apache error log for the specific reason

sudo tail -f /var/log/apache2/error.log

Expected output:

[Mon Jan 15 10:30:00.123456 2024] [authz_core:error] [pid 12345] [client 192.168.1.1:54321] AH01630: client denied by server configuration: /var/www/html/

The error code AH01630 means a Require directive explicitly denied access.

4. Allow Apache through the firewall

sudo ufw status

Expected output:

Status: active
To                         Action      From
Apache Full                ALLOW       Anywhere

If Apache is not listed:

sudo ufw allow 'Apache Full'

5. Check SELinux context (RHEL/Fedora/CentOS)

ls -Z /var/www/html/

If the context is wrong, restore it:

sudo restorecon -Rv /var/www/html/

6. Restart Apache and test

sudo apachectl configtest
sudo systemctl restart apache2  # or httpd

Expected output:

Syntax OK

Then test:

curl http://localhost/

Expected output:

<!DOCTYPE html>
<html>

7. Check for .htaccess file restrictions

ls -la /var/www/html/.htaccess

If a .htaccess file exists, check if it contains Deny from all or Require all denied. Temporarily rename it to test:

mv /var/www/html/.htaccess /var/www/html/.htaccess.bak

8. Check SELinux context on the document root

ls -Z /var/www/html/

If the context is default_t instead of httpd_sys_content_t, restore it:

sudo restorecon -Rv /var/www/html/

Prevention

  • Set the document root directory owner to www-data (or apache on RHEL-based systems)
  • Use Require all granted in Directory blocks — never use Deny from all unless you specifically need IP-based restrictions
  • Always run apachectl configtest after editing configuration files to catch syntax errors
  • Use 755 permissions for directories and 644 for files under the document root
  • Check both error.log and access.log when debugging — the error log provides the exact AH code for the reason

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro