Skip to main content
Blog|
How-to guides

WordPress 403 forbidden error: how to fix it

|
Mar 25, 2026|10 min read
HOW-TO GUIDESWordPress 403 forbidden error:how to fix itHOSTNEYhostney.comMarch 25, 2026

A 403 Forbidden error means the server understood your request but is refusing to fulfill it. Unlike a 404 where the resource does not exist, or a 500 where the server crashed, a 403 means the server found what you asked for and deliberately said no.

In a WordPress context, 403 errors show up in several ways: you cannot access wp-admin, a specific page returns 403 for some visitors but not others, file uploads fail with a 403, or an AJAX request to admin-ajax.php is blocked. Each scenario has different causes, but they all come down to the same thing – something between the browser and WordPress is rejecting the request.

What generates a 403#

Multiple layers can produce a 403 response, and identifying which layer is blocking the request is the first diagnostic step.

Web server (Nginx or Apache). The server itself can return 403 if directory listing is disabled and no index file exists, if file permissions prevent the web server from reading a file, or if a configuration directive explicitly denies access to a path.

Web application firewall (WAF). ModSecurity, Imunify360, or other WAF software inspects requests for malicious patterns. If a request body, URL, or header matches a rule, the WAF returns 403 before the request reaches WordPress.

Security plugins. Wordfence, Sucuri, iThemes Security, and similar plugins run inside WordPress and can return 403 for blocked IPs, blocked countries, rate-limited requests, or requests that match their firewall rules.

Server-level bot detection. Hosting infrastructure may block requests at the edge based on IP reputation, request patterns, or behavioral signals. This produces a 403 or a challenge page before the request reaches PHP.

File permissions. If the web server process cannot read a PHP file, it returns 403 instead of executing it. This is different from a WordPress-level permission check.

The first step is always to determine which layer produced the 403. The response body and headers tell you.

Diagnosing the source#

Check the response body

Open your browser’s developer tools (F12), go to the Network tab, and load the page that returns 403. Click on the request and examine the response:

  • A styled HTML page with your site’s design = WordPress or a WordPress plugin generated the 403. The request reached PHP.
  • A plain error page or generic server page = The web server or WAF blocked the request before it reached WordPress.
  • A challenge page (proof-of-work puzzle, CAPTCHA) = Server-level bot detection flagged the request. This is technically not a 403 but can appear similar.

Check the error logs

Nginx error log – shows 403 responses generated by the web server itself:

tail -100 /var/log/nginx/error.log | grep "403"

ModSecurity audit log – shows WAF rule triggers:

grep "ModSecurity" /var/log/nginx/error.log

WordPress debug log – if a plugin generated the 403, it may have logged the reason:

tail -50 wp-content/debug.log

PHP error log – shows permission errors when PHP cannot read files. On Hostney, per-site logs are at ~/.logs/{your-domain}-php.error.log .

Cause 1: Security plugin blocking your IP#

The most common cause of 403 errors on WordPress sites. Security plugins maintain blocklists and will lock out IP addresses that trigger their rules – too many failed login attempts, requests to sensitive files, or traffic patterns that look automated.

How to confirm

Try accessing the site from a different network (mobile data instead of Wi-Fi, or a VPN). If it loads, your IP is blocked.

How to fix

If you can still access wp-admin from a different IP, log in and check the security plugin’s blocked IP list. Whitelist your IP address.

If you cannot access wp-admin at all, deactivate the security plugin via SFTP:

cd wp-content/plugins/
mv wordfence wordfence-disabled

The block is removed because the plugin is no longer running. Log in, reactivate the plugin, and whitelist your IP before it locks you out again.

For a deeper discussion of how security plugins interact with server-level protections, see Wordfence and server-level security: why you need both.

Preventing future lockouts

Most security plugins have a setting to whitelist specific IPs from lockout rules. If you have a static IP address, add it. If your IP changes (most residential ISPs), configure the plugin to be less aggressive with lockout thresholds or reduce the lockout duration.

Cause 2: WAF rule triggered by post content#

Web application firewalls inspect request bodies for patterns that look like attacks – SQL injection ( ' OR 1=1 ), cross-site scripting ( <script> ), path traversal ( ../../ ), and command injection. If you are writing a blog post about security, coding, or system administration, your post content may contain these patterns as examples and trigger a WAF rule.

How to confirm

The 403 happens when saving or publishing a specific post, not when loading pages. The error appears in the block editor as “Updating failed” (which is the REST API request being blocked). Check the server error log for ModSecurity entries with the specific rule ID that triggered.

For a complete walkthrough of REST API save failures, see WordPress “Updating failed” or “Publishing failed”: how to fix it.

How to fix

On self-managed servers, whitelist the specific ModSecurity rule that triggered. The rule ID is in the audit log.

On managed hosting, contact support with the error details. Most hosts can adjust WAF sensitivity for the WordPress admin area or whitelist specific rules.

Workaround

If you need to publish the content immediately, try encoding the triggering content differently – wrap code examples in <pre> tags, use screenshots instead of inline code, or split the content across multiple saves. This is a workaround, not a fix – the WAF rule should be adjusted so it does not block legitimate content.

Cause 3: File permissions too restrictive#

If the web server process cannot read a PHP file or a directory, it returns 403. This happens after permission changes, file transfers that did not preserve permissions, or security hardening that was too aggressive.

How to confirm

The 403 applies to specific files or directories, not the entire site. The Nginx error log shows “permission denied” entries.

How to fix

Reset permissions to the WordPress standard:

# Directories: 755 (owner rwx, group rx, others rx)
find /path/to/wordpress -type d -exec chmod 755 {} \;

# Files: 644 (owner rw, group r, others r)
find /path/to/wordpress -type f -exec chmod 644 {} \;

# wp-config.php: more restrictive
chmod 640 wp-config.php

The file owner must be the user that PHP runs as. If files are owned by root or a different user, PHP-FPM cannot read them:

chown -R youruser:youruser /path/to/wordpress

On Hostney, each site runs in its own container where PHP-FPM runs as the account user. File ownership is set correctly during provisioning. If permissions drift (usually after a manual file transfer or a plugin that creates files incorrectly), the platform corrects them automatically in the background. For a complete reference on file permissions, see Linux file permissions: chmod and chown explained.

Some hosts or security configurations block direct access to files in certain directories – either to prevent hotlinking (other sites embedding your images) or to prevent directory listing (browsing your file structure).

How to confirm

The 403 only occurs when accessing specific file types (images, CSS, JS) directly via URL, or when accessing a directory without an index file.

How to fix

Hotlinking: If hotlink protection is blocking legitimate requests (like your own site loading its own images), check the referrer-based rules. On Apache, these are in .htaccess . On Nginx, they are in the server configuration.

Directory listing: Nginx disables directory listing by default ( autoindex off ). This is correct behavior – you do not want visitors browsing your wp-content directory. The 403 is expected if someone navigates to a directory URL. If a plugin or theme needs directory listing for a specific path, that is a plugin configuration issue, not a server issue.

Cause 5: Country or IP range blocking#

Security plugins and server-level configurations can block entire countries or IP ranges. This is a legitimate security practice for sites that only serve specific regions, but it produces 403 errors for visitors outside the allowed regions.

How to confirm

The 403 affects visitors from specific geographic locations but not others. Check your security plugin’s country blocking settings. On server-level configurations, check firewall rules.

How to fix

If you intentionally set up country blocking, the 403 is working as designed. Ensure your own IP or country is whitelisted.

If you did not set up country blocking, check for:

  • Security plugin geo-blocking settings that were enabled accidentally
  • A previous administrator who configured country restrictions
  • Server-level firewall rules set by your hosting provider

Cause 6: .htaccess rules (Apache only)#

On Apache, .htaccess can contain rules that deny access to specific files, directories, or request types. A misconfigured .htaccess can block legitimate requests.

How to confirm

This only applies to sites running on Apache. On Hostney, Nginx is the default, and .htaccess files are ignored. If you have switched to Apache for a legacy site (configurable under Hosting > Subdomains), check .htaccess for deny rules.

How to fix

Look for Deny from all or Require all denied directives in .htaccess :

grep -n "Deny\|deny\|Require all denied" .htaccess

Common legitimate rules that can cause problems:

# This blocks all direct access to PHP files in wp-content
<Files *.php>
    Require all denied
</Files>

This is a security rule found in wp-content/.htaccess and wp-includes/.htaccess . It prevents direct execution of PHP files in those directories. If a plugin needs to be accessed directly via URL (some payment gateways use callback URLs pointing to plugin PHP files), this rule breaks it. The fix is to add an exception for the specific file.

Cause 7: Bot detection and automated traffic filtering#

Modern hosting platforms detect and block automated traffic based on behavioral signals – request rate, header patterns, IP reputation, and more. If your request is misidentified as automated, you may see a 403 or a challenge page.

How to confirm

The 403 comes from the server infrastructure, not from WordPress. The response is a plain page or a proof-of-work challenge, not a WordPress-themed error. It may affect only certain IP addresses or networks.

How to fix

If your own IP is being flagged:

  • Check if you are using a VPN or proxy. Shared VPN IPs often have poor reputation because other users on the same IP engaged in abuse. Try accessing the site without the VPN.
  • Check if your IP was recently involved in a traffic spike. Rate detection systems respond to sudden increases in request volume. If you were running automated tools (load testing, crawlers, API scripts) against the site, the system may have flagged your IP.

If legitimate visitors are being blocked, check your hosting platform’s bot detection settings. On Hostney, the bot detection system differentiates between hard blocks (for extreme rate spikes), challenges (for suspicious traffic that could be human), and scoring-based decisions (for longer-term reputation tracking). Verified search engine bots are automatically exempted. You can also whitelist specific IPs per domain. See What happens when bots find your WordPress login for context on how bot traffic is handled.

Cause 8: REST API or AJAX blocked#

If the 403 specifically affects wp-admin AJAX requests or REST API calls, the cause is usually a security plugin or WAF rule targeting those endpoints. This manifests as broken admin features – the Customizer does not save, bulk actions fail, or the block editor cannot publish.

How to confirm

Open developer tools, go to the Network tab, and perform the action that fails. Look for requests to admin-ajax.php or /wp-json/ that return 403.

How to fix

Check security plugin settings for REST API or AJAX restrictions. Some plugins have a “disable REST API for non-authenticated users” setting that should not affect logged-in admins but sometimes does due to cookie or nonce issues.

Clear all caches – a stale nonce in a cached page causes the server to reject the request as unauthenticated.

403 on wp-admin specifically#

If the entire wp-admin area returns 403 but the front-end works, common causes include:

  • IP-based restriction on wp-admin. Some security configurations restrict wp-admin access to specific IP addresses. If your IP changed (ISP reassigned it), you are locked out. Check  .htaccess  (Apache) or server configuration for IP restrictions on the admin area.
  • HTTP authentication (basic auth). A  .htpasswd  layer was added to wp-admin for extra security, and the credentials are not being sent correctly.
  • Hosting-level restriction. Some hosts restrict wp-admin access during detected attacks (DDoS, brute force campaigns). Contact your host.

Summary#

A 403 error means something deliberately blocked the request. The diagnostic sequence is: check the response body to identify which layer produced the 403 (WordPress plugin, WAF, web server, or infrastructure), check the corresponding error log for the specific reason, then apply the fix for that layer.

The most common causes on WordPress sites are security plugins blocking your IP after too many failed logins, WAF rules triggering on post content that resembles attack patterns, and file permissions preventing the web server from reading files. All three are fixable without deep technical knowledge once you identify which one applies. For a complete reference of WordPress errors and their quick fixes, see How to fix the most common WordPress errors.

Related articles