image

How To Fix a 403 Forbidden Error on Your VPS

Published : October 7, 2025
Last Updated : October 7, 2025
Published In : Uncategorized

You are trying to access your website and boom, 403 Forbidden Error. The server understood your request perfectly but decided to slam the door in your face anyway. This is not a “page not found” situation. The page exists. The server just will not let you see it. And if you are running a VPS, chances are you caused this yourself. Don’t worry, it happens to everyone. At Virtarix, we often see users run into 403 errors. With over a decade of experience in cloud hosting, we understand their root causes and how to fix them quickly.

Here is the thing about VPS hosting. You have full control. That is powerful. But it also means you can accidentally lock yourself out of your own site by changing the wrong permission, messing up an .htaccess rule, or letting your firewall get a little too aggressive.

Understanding the 403 Forbidden Error

A 403 error means the server understood your request but refused to process it due to insufficient permissions or application logic restrictions. Think of it like showing up to a private party. The bouncer knows you are there, but you are not on the list.

The server is not broken. The file exists. You just do not have permission to access it.

This is different from a 404 error where the page does not exist at all, or a 401 error where you need to log in with credentials. With a 403, even if you had a username and password, it would not help. The problem is deeper. It is about server-level permissions.

On a VPS, you will see 403 errors more often than on shared hosting because you are managing everything yourself. On shared hosting, the host sets safe defaults. On a VPS, if you set file permissions to something unusual at 2 AM while troubleshooting another issue, you may find out the next morning that you have caused the error.

Step-by-Step Guide to Fix 403 Forbidden Error

Start simple. Don’t immediately SSH into your server and start changing permissions. Rule out the easy stuff first.

Step 1: Check the Simple Stuff First

Refresh the page because many 403 errors are temporary. Press Ctrl+Shift+R (or Cmd+Shift+R on Mac) to do a hard refresh that bypasses your browser cache.

Check the URL carefully. If you are trying to access a directory without a trailing slash or with a typo, you might hit a 403. For example, example.com/admin might work while example.com/admin/ returns 403 if there is no index file in that folder.

Clear your browser cache and cookies. Old cached permission states can cause phantom 403 errors. Better yet, test in an incognito or private window. It starts clean every time.

If you are using a VPN or proxy, turn it off temporarily. VPN IP addresses often get abused and end up on blocklists. Try accessing your site from your phone on cellular data, not WiFi. If it works there but not on your computer, the problem is on your end. It could be cached data, a browser extension, or your IP is blocked.

Browser-Level Checks
Open your browser developer tools (F12), go to the Network tab, and reload the page. Look at the response headers for the failed request. This shows you whether the 403 is coming from your server, a CDN, or something in between.


Network-Level Checks
You can also use curl to quickly diagnose where the 403 is coming from:

				
					curl -I https://yoursite.com
				
			

Look for these headers in the output:

  • Server: tells you if it is Apache, Nginx, or a CDN responding

  • X-Powered-By: might reveal if PHP is involved

  • CF-Ray: indicates Cloudflare is in the path

Status code 403 with Server: cloudflare means the CDN is blocking you, not your VPS.

If you see your actual server name (like Apache/2.4.41 or nginx/1.18.0), the block is coming from your VPS, not external services.

Step 2: Fix File Permissions via SSH

This step is where you will fix 80% of permission-based 403 errors. You need SSH access to your VPS for this. 

Connect to your server and navigate to your web root (usually /var/www/html or /home/username/public_html).

Check current permissions with:

				
					ls -la
				
			

You will see output like -rw-r–r– for files and drwxr-xr-x for directories. If you see anything like -rw——- or drwx——, that is the problem.

Fix directory permissions:

				
					find /var/www/html -type d -exec chmod 755 {} \;
				
			

Fix file permissions:

				
					find /var/www/html -type f -exec chmod 644 {} \;
				
			

These commands recursively set correct permissions. 755 on directories means the owner can read, write, and execute. Everyone else can read and execute, which means they can navigate through. 644 on files means the owner can read and write. Everyone else can only read.

CRITICAL WARNING: Never use 777 permissions. Yes, it fixes permission errors immediately. It also lets anyone execute any code on your server. Servers can be compromised within hours of setting 777 permissions because bots scan for them.

All Virtarix VPS plans grant full root access, giving you complete flexibility to correct permissions without delay.

If you are running WordPress or another CMS, some files need special permissions. For example, WordPress needs wp-config.php set to 600 or 640 for security. Always check your CMS documentation.

Step 3: Fix File Ownership

Even with correct permissions, wrong ownership breaks everything. Your web server needs to be able to read files.

Check current ownership:

				
					ls -la

				
			

Look for the username and group in the third and fourth columns. If they are both root, that is likely the issue.

Find out what user your web server runs as:

				
					ps aux | grep -E 'apache|nginx|httpd'
				
			

Usually it is www-data, nginx, apache, or nobody. Let’s say it is www-data.

Fix ownership recursively:

				
					chown -R www-data:www-data /var/www/html
				
			

This changes both the user and group ownership. Now your web server can access the files even if permissions are restrictive.

For WordPress, you typically want files owned by your user account so you can edit them, but readable by www-data so the web server can serve them.

In that case:

				
					chown -R yourusername:www-data /var/www/html
				
			

Then make sure group permissions are set correctly. Look for the r in the group permission section.

Step 4: Check Your .htaccess File

If you are running Apache, .htaccess files control access. A single bad rule can lock everyone out.

First, test if .htaccess is the problem.

Rename it:

				
					mv .htaccess .htaccess.backup
				
			

Refresh your site. If it works now, .htaccess was the culprit.

Most common .htaccess mistakes include:

  • Deny from all without a corresponding Allow statement

  • Requiring authentication that is not configured

  • Rewrite rules that create infinite loops

  • IP whitelisting that does not include your current IP

Apache 2.4 Syntax Change: If you are running Apache 2.4 or newer, the old access control syntax does not work anymore. Lines like:

				
					Order allow,deny
Allow from all

				
			

will cause 403 errors. You need to use the new syntax:

				
					Require all granted
				
			

Or to allow specific IPs:

				
					Require ip 192.168.1.100
				
			

If you are using WordPress, you can regenerate a default .htaccess by going to 

Settings → Permalinks and clicking Save. WordPress writes a fresh .htaccess file.

For a basic WordPress .htaccess:

				
					# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

				
			

Restore your old .htaccess one section at a time to find the problematic rule.

Step 5: Verify Index Files Exist

If you are getting a 403 on a directory, check if an index file exists.

				
					ls -la /var/www/html/blog/
				
			

Look for index.html, index.php, or whatever your default document is set to in your web server config.

If it is missing, you have three options:

  • Add an index file

  • Enable directory listing (not recommended for security)

  • Set up a redirect

For Apache, your default document order is usually defined in the main config or virtual host file. It typically prioritizes index.html, then index.php, then others.

If you see an index file but still get 403 errors, the file itself might have wrong permissions:

				
					chmod 644 /var/www/html/blog/index.php
				
			

Step 6: Verify Virtual Host Configuration

If you host multiple sites on your VPS, the wrong virtual host config might be served for your domain.

For Apache, check which virtual hosts are enabled:

				
					apache2ctl -S
				
			

or on CentOS/RHEL:

				
					httpd -S
				
			

This shows all configured virtual hosts and which one matches your domain. Look for your domain in the output and verify it points to the correct document root.

For Nginx, check your site configuration:

				
					nginx -T | grep server_name
				
			

If your domain is not listed or points to the wrong location, edit your virtual host file.

  • For Apache, it is usually in /etc/apache2/sites-available/ or /etc/httpd/conf.d/.

  • For Nginx, check /etc/nginx/sites-available/ or /etc/nginx/conf.d/.

After making changes, test the configuration:

				
					apache2ctl configtest
				
			

or for Nginx:

				
					nginx -t
				
			

Then restart the web server:

				
					systemctl restart apache2
				
			

or

				
					systemctl restart nginx
				
			

Step 7: Fix Symlink Issues

If error logs mention symlinks or you are using symbolic links, your server may have symlink following disabled.

For Apache, add this to your .htaccess file or virtual host configuration:

				
					Options +FollowSymLinks
				
			

For Nginx, symlinks are followed by default, but check for any disable_symlinks directives that may be blocking them.

After making changes, restart the service:

				
					systemctl restart apache2
				
			

Or for Nginx:

				
					systemctl restart nginx
				
			

Step 8: Check for IP Blocks

Another common cause of 403 errors is when your server blocks your IP address using tools like fail2ban, firewalls, or security plugins.

Check fail2ban first (if installed):

				
					fail2ban-client status
				
			

This shows active jails. Then check if your IP is banned:

				
					fail2ban-client status [jail-name]
				
			

If your IP is in the banned list, unban it:

				
					fail2ban-client set [jail-name] unbanip YOUR.IP.ADDRESS
				
			

Important: If your IP keeps getting banned, it will only happen again unless you fix the root cause (like repeated failed logins). Alternatively, whitelist your IP permanently.

Also, check firewall rules:

				
					iptables -L -n
				
			

Or with UFW:

				
					ufw status
				
			

If you use a CMS like WordPress with security plugins (Wordfence, iThemes Security), log into the admin panel and review blocked IPs.

Sometimes, shared IPs on VPNs or mobile networks get flagged. In this case, whitelisting your IP or IP range is the best fix.

Step 9: Check mod_security Rules

If your VPS has mod_security installed (very common on cPanel or hardened servers), it may block legitimate requests.

To check if it is active:

				
					apachectl -M | grep security
				
			

Or check your Apache error logs:

				
					grep -i "ModSecurity" /var/log/apache2/error.log
				
			

You’ll see entries with rule IDs that triggered the block. These often cause false positives for form submissions, file uploads, or certain patterns.

To temporarily disable mod_security for testing, add this to .htaccess:

				
					<IfModule mod_security.c>
SecRuleEngine Off
</IfModule>

				
			

If your site works afterward, you will need to whitelist specific rules or adjust the configuration.

For cPanel users, go to:

				
					 WHM → Security Center → ModSecurity Tools 
				
			

to manage rules.

Step 10: Check PHP-FPM Permissions (Nginx Users)

If you are running Nginx with PHP-FPM, permission issues often happen when PHP-FPM runs under a different user than the file owner.

Check what user PHP-FPM runs as:

				
					ps aux | grep php-fpm
				
			

It is usually www-data or nginx. This user must have read access to your PHP files.

Next, check your pool configuration:

				
					cat /etc/php/7.4/fpm/pool.d/www.conf | grep -E 'user|group'
				
			

(Adjust the PHP version as needed). Make sure the user and group match file ownership or that group permissions allow access.

If you need to change the PHP-FPM user, edit the pool configuration and restart:

				
					systemctl restart php7.4-fpm
				
			

Step 11: Troubleshoot CDN Issues

If you are using a CDN (Cloudflare, StackPath, etc.), it might be blocking requests or caching old permissions.

To test, temporarily disconnect your CDN. In Cloudflare, set DNS to DNS only (gray cloud) instead of Proxied (orange cloud).

If the site works without the CDN, the issue lies in the CDN configuration. Try purging the cache:

  • Cloudflare: Go to Caching → Configuration → Purge Everything.

     

Also, review CDN firewall rules. In Cloudflare, the Firewall tab shows blocked requests and allows you to whitelist your IP.

Some CDNs display challenge pages that appear as 403 errors. Lowering security settings temporarily can confirm this.

Step 12: Verify DNS Points to the Right Server

Sometimes DNS points to an old VPS you migrated from.

Check your domain’s A record:

				
					dig yourdomain.com A
				
			

or

				
					nslookup yourdomain.com
				
			

Compare the result to your current VPS IP. If it’s wrong, update your A record at your DNS provider.

Modern DNS usually updates in minutes to hours, though high TTL values can delay propagation up to 24 hours.

Flush your local DNS cache to see changes faster:

  • Windows:

				
					ipconfig /flushdns
				
			

  • Mac:

				
					sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
				
			

  • Linux:

				
					sudo systemd-resolve --flush-caches
				
			

Step 13: Check Server Error Logs

When all else fails, check the error logs. They usually tell you exactly what’s wrong.

For Apache:

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

For Nginx:

				
					tail -f /var/log/nginx/error.log
				
			

On Virtarix, you always have SSH access to logs. If you need help interpreting them, our support team is available around the clock.

Reproduce the 403 error while watching the logs. You’ll see messages like Permission denied, Directory index forbidden by Options directive, or specific module errors.

Common log messages explained:

  • “Permission denied: access to / denied” → file permissions issue

     

  • “Options FollowSymLinks and SymLinksIfOwnerMatch are both off”.htaccess or server config restricting symlinks

     

  • “client denied by server configuration”.htaccess or virtual host rules blocking access

     

  • “AH01630: client denied by server configuration” → Apache 2.4 syntax for access denial

     

These logs usually point you directly to the problem.

When to Contact Support

You’ve checked permissions, ownership, .htaccess, firewall rules, virtual hosts, and CDN settings. You’ve read the logs. Nothing works. Now it’s time to contact support if you have managed support with your VPS provider.

Before you do, gather information. You’ll need the exact error message, the URL that’s returning 403, recent changes you made to the server, relevant error log entries, and your current IP address.

Good support can check server level configs you don’t have access to. This includes the main Apache or Nginx config, SELinux or AppArmor settings if enabled, or mod_security rules that might be too aggressive.

Check SELinux Issues

If you have root access and you’re on RHEL, CentOS, or Fedora, check if SELinux is causing issues:

				
					getenforce
				
			

If it returns Enforcing, SELinux might be blocking access even with correct permissions.

Check SELinux contexts on your files:

				
					ls -Z /var/www/html
				
			

You should see contexts like httpd_sys_content_t for web files. If they’re wrong, restore the correct contexts:

				
					restorecon -R /var/www/html
				
			

To temporarily disable SELinux for testing:

				
					setenforce 0
				
			

If that fixes it, SELinux file contexts need adjustment. Note that this change won’t survive a reboot. For permanent changes, you need to configure SELinux policies properly or disable it in /etc/selinux/config.

But this is advanced territory. If you’re not familiar with SELinux, contact support rather than permanently disabling it. SELinux provides important security benefits when configured correctly.

 

Check AppArmor Issues (Ubuntu Users)

Ubuntu uses AppArmor instead of SELinux. If you’re getting unexplained 403 errors on Ubuntu, AppArmor might be the culprit.

Check if AppArmor is enabled:

				
					sudo aa-status
				
			

This shows which profiles are loaded and in enforce mode. Look for profiles related to Apache or Nginx.

Check AppArmor logs for denials:

				
					sudo grep -i apparmor /var/log/syslog | grep DENIED
				
			

If you see denials related to your web server, you can temporarily put the profile in complain mode:

				
					sudo aa-complain /etc/apparmor.d/usr.sbin.apache2
				
			

or for Nginx:

				
					sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
				
			

If your site works in complain mode, the AppArmor profile needs adjustment. This is complex territory, so contact support or consult AppArmor documentation.

Preventing Future 403 Errors

Once you’ve fixed it, let’s make sure it doesn’t happen again.

Document your permission scheme. When you set up a site, note down what user and group owns the files and what permissions they have. When you migrate or restore from backup, you’ll know exactly what to set.

Be careful with .htaccess edits. Before modifying it, make a backup:

				
					cp .htaccess .htaccess.backup-$(date +%F)
				
			

Test changes on a staging environment first, not production.

Update your CMS and plugins regularly. Old plugins with security issues get patched, and sometimes those patches change permission requirements or add stricter access controls. After major WordPress updates, verify that your file permissions haven’t been reset.

Monitor fail2ban activity. Occasionally review banned IPs to make sure legitimate users aren’t getting blocked:

				
					fail2ban-client status [jail-name]
				
			

If you see your own IP repeatedly banned, adjust your fail2ban threshold or whitelist your IP.

Keep documentation of your DNS records. When you change hosting or move servers, you’ll know exactly what records to update. A simple text file with your A records, MX records, and nameservers saves hours of troubleshooting.

Use version control for config files. Keep your .htaccess, Nginx conf files, and other configs in a git repo. When something breaks, you can diff against the last working version and find exactly what changed.

Review mod_security logs periodically if you have it enabled. Look for false positives that might be blocking legitimate users and adjust rules accordingly.

Test virtual host configs after adding new sites. Run:

				
					apache2ctl -S
				
			

or

				
					nginx -t
				
			

To verify your configuration is correct before restarting the web server.

Set up monitoring. Use a service like UptimeRobot or StatusCake to alert you immediately when your site returns a 403. The faster you catch issues, the less impact they have.

A reliable VPS foundation helps prevent errors before they even happen. Virtarix’s infrastructure and support help you maintain that stability with confidence. Explore our VPS solutions today and see how Virtarix can power your projects with speed, reliability, and 24/7 support.

Content 1 Content 1 Content 1
Content 2 Content 2 Content 2

About the Author Peter French is the Managing Director at Virtarix, with over 17 years in the tech industry. He has co-founded a cloud storage business, led strategy at a global cloud computing leader, and driven market growth in cybersecurity and data protection.

Other posts

image
October 7, 2025
Published in : Uncategorized
How To Fix a 403 Forbidden Error on Your VPS

You are trying to access your website and boom, 403 Forbidden Error. The server understood your request perfectly but decided to slam the door in your face anyway.

image
October 3, 2025
Published in : Technical Guide
How to Host Docker on VPS in 2025

Docker solves a problem every developer faces: “It works on my machine, but not in production.” This guide shows you how to host on VPS in 2025.

image
October 1, 2025
Published in : Technical Guide
How to Self-Host Bitwarden on a VPS in 2025

In this guide, we walk you through setting up Bitwarden on a VPS using the latest software and best practices available right now.

Listed on WHTop.com Listed on WHTop.com

© 2025 : Virtarix. All Rights Reserved