How to Fix Apache 403 Forbidden Error
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(orapacheon RHEL-based systems) - Use
Require all grantedin Directory blocks — never useDeny from allunless you specifically need IP-based restrictions - Always run
apachectl configtestafter editing configuration files to catch syntax errors - Use
755permissions for directories and644for files under the document root - Check both
error.logandaccess.logwhen debugging — the error log provides the exact AH code for the reason
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro