Seeing “403 Forbidden — You don’t have permission to access this resource” means the web server received and understood your HTTP request, but explicitly refuses to serve the requested file or directory.
In WordPress and web hosting environments, 403 errors frequently strike during wp-admin logins, plugin installations, or REST API submissions. The issue is almost always caused by misconfigured Linux file permissions, restrictive .htaccess directives, or an overly aggressive Web Application Firewall (WAF) rule.
Quick Answer
- Correct filesystem permissions across your WordPress installation:
find /var/www/html -type d -exec chmod 755 {} \; find /var/www/html -type f -exec chmod 644 {} \; - Verify that the web server user owns the document root:
chown -R www-data:www-data /var/www/html - If permissions are correct, inspect
.htaccessfor IP blocks orDeny from allrules. - If you are using cPanel or ModSecurity, check the ModSecurity audit log for false-positive firewall blocks.
Symptoms
- Accessing
yourdomain.com/wp-admin/orwp-login.phpdisplays: “403 Forbidden: Access Denied”. - Uploading images in the WordPress Media Library fails with HTTP 403 errors.
- REST API calls or AJAX actions return
403 (Forbidden)in browser developer tools (F12 -> Network). - Direct visits to subdirectories return 403 because directory browsing is disabled and no
index.phpexists.
Common Causes
- Incorrect Linux File/Folder Permissions: Folders set to
000or700, or files owned byrootinstead of the web server user (www-data,nginx, or cPanel account user). - Restrictive
.htaccessDirectives: Security plugins addingDeny from allor blocking specific User-Agents, request headers, or IP ranges. - ModSecurity Web Application Firewall Blocks: The OWASP Core Rule Set detecting a false positive in a WordPress POST payload (e.g., passing raw HTML or SQL-like terms in a contact form).
- Security Plugin Lockout: Plugins like Wordfence, Solid Security, or Sucuri blocking your current IP address after failed login attempts.
- Missing Index File: A directory does not contain an
index.phporindex.htmlfile, and directory indexing (Options -Indexes) is enforced.
Before You Start
- Never attempt to solve a 403 error by running
chmod -R 777. Giving world-writeable permissions is dangerous and modern hosting configurations will block 777 permissions with a 500 Internal Server Error. - Check whether the 403 occurs for all visitors or only from your specific office/home IP address.
- For enterprise compliance environments, see our server security guidelines.
Step 1 — Reset Standard WordPress File and Directory Permissions
The most common source of 403 errors on Linux servers is incorrect filesystem permissions or ownership.
Navigate to your WordPress document root (e.g., /var/www/html or /home/username/public_html):
cd /var/www/html
Apply Standard Directory Permissions (755)
Directories must be executable and readable (rwxr-xr-x):
find . -type d -exec chmod 755 {} \;
Apply Standard File Permissions (644)
Files should be readable by all, but writeable only by the owner (rw-r--r--):
find . -type f -exec chmod 644 {} \;
Secure wp-config.php (600 or 640)
Restrict access to database credentials:
chmod 600 wp-config.php
Ensure Correct Ownership
The web server daemon must own the files to read and execute PHP scripts:
# On Ubuntu/Debian:
chown -R www-data:www-data /var/www/html
# On AlmaLinux / Rocky / Nginx:
chown -R nginx:nginx /var/www/html
# On cPanel servers (replace 'username' with your cPanel account name):
chown -R username:username /home/username/public_html
Step 2 — Inspect and Reset the .htaccess File
Security plugins and firewall rules frequently modify .htaccess to block specific directories, query strings, or IP addresses.
Inspect .htaccess for restrictive blocks:
grep -i -E "deny|forbidden|block" /var/www/html/.htaccess
Test by Temporarily Renaming .htaccess
mv /var/www/html/.htaccess /var/www/html/.htaccess.test
Refresh your browser:
- If the 403 error disappears: The
.htaccessfile contained the blocking directive. - Replace it with the default, clean WordPress
.htaccessconfiguration:
cat << 'EOF' > /var/www/html/.htaccess
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
EOF
Step 3 — Check ModSecurity WAF False Positives
If permissions and .htaccess are clean, a Web Application Firewall (WAF) like ModSecurity is actively intercepting your request.
In cPanel / WHM:
- Log into WHM or cPanel.
- Navigate to ModSecurity Tools or Security Center -> ModSecurity.
- Search for recent hits corresponding to your public IP address.
- If a rule (e.g.,
Rule ID: 941100) blocked your request, temporarily whitelist that specific rule ID for the affected domain.
On Ubuntu/Debian Command Line:
Inspect the ModSecurity audit log:
tail -n 50 /var/log/apache2/modsec_audit.log || tail -n 50 /var/log/nginx/modsec_audit.log
Look for lines indicating ModSecurity: Access denied with code 403 (phase 2). Identify the offending rule ID and adjust your rule exclusions in /etc/modsecurity/.
Step 4 — Deactivate WordPress Security Plugins
Security plugins (such as Wordfence, iThemes/Solid Security, or All-in-One Security) maintain their own internal firewalls and rate limiters. If you enter an incorrect password multiple times, your IP address is locked out with a 403 error.
Deactivate via WP-CLI:
wp plugin deactivate wordfence --path=/var/www/html --allow-root
Or rename the security plugin’s folder to disable it:
mv /var/www/html/wp-content/plugins/wordfence /var/www/html/wp-content/plugins/wordfence.bak
If your IP was locked in the database, clear the plugin’s lockout transient table or restart your home router to obtain a fresh public IP address.
Step 5 — Verify the Presence of index.php
If you receive a 403 error when visiting a specific subfolder (like /wp-content/uploads/ or a custom subfolder), this is often intentional.
When directory browsing is disabled on Apache/Nginx (Options -Indexes), requesting a folder that contains no index.php or index.html file causes the server to return 403 Forbidden.
Verify that index.php exists in your main directory:
ls -la /var/www/html/index.php
If index.php is missing from the root, download the official WordPress archive and restore the missing core file:
wp core download --skip-content --force --allow-root
Step 6 — Verify Resolution
- Open your website in a private browsing window to bypass cached authorization headers.
- Attempt to log in to
/wp-admin/. - Test media uploads and save changes to a draft post to confirm write operations succeed.
Common Mistakes
- Setting folders to 777: Running
chmod 777exposes your entire site to local file inclusion attacks. Use755for directories and644for files. - Deleting .htaccess permanently: Removing
.htaccesswithout recreating the default WordPress rewrite rules will break all internal pretty permalinks, causing 404 errors across all blog posts and pages. - Disabling ModSecurity globally: Never disable ModSecurity across the entire server. Whitelist only the specific false-positive rule ID for the affected domain.
Prevention Checklist
- Maintain strict standard permissions (
755for directories,644for files). - Regularly audit security plugin lockout lists and whitelist your administrative static IP address.
- Configure your Web Application Firewall rules to ignore authenticated administrators.
- Consult our WordPress server support and cPanel support specialists for server-level WAF tuning.
Quick Reference Commands
| Task | Command |
|---|---|
| Set directory permissions | find /var/www/html -type d -exec chmod 755 {} \; |
| Set file permissions | find /var/www/html -type f -exec chmod 644 {} \; |
| Fix web ownership (Ubuntu) | chown -R www-data:www-data /var/www/html |
| Secure wp-config.php | chmod 600 /var/www/html/wp-config.php |
| Deactivate security plugin | wp plugin deactivate <plugin-slug> --allow-root |
| Check ModSec log | tail -f /var/log/apache2/modsec_audit.log |
Frequently Asked Questions
Why do I get a 403 error only when uploading images?
This indicates that the /wp-content/uploads/ directory does not have write permissions for the web server user (www-data or nginx). Run chmod 755 /var/www/html/wp-content/uploads and ensure ownership matches your web server user.
Why does 403 Forbidden appear only on wp-admin?
Many hosting providers and security plugins restrict /wp-admin/ or wp-login.php to specific whitelisted IP addresses. Check /wp-admin/.htaccess or your security plugin settings for IP restriction rules.
Can Cloudflare cause a 403 Forbidden error?
Yes. If Cloudflare’s Web Application Firewall, Bot Fight Mode, or Under Attack Mode identifies your request as suspicious, Cloudflare will return a branded 403 Forbidden or 1020 Access Denied screen before traffic ever reaches your origin server.
How does ServerCare360 help resolve server permission and security errors?
Our certified server security and emergency server support engineers audit Linux access permissions, configure custom ModSecurity rule exclusions, resolve security plugin lockouts, and harden WordPress installations 24/7.