WordPress 403 Forbidden: find which layer said no
In short
A WordPress 403 Forbidden error means something refused the request on purpose. It is usually a security plugin or firewall rule, a stale login check after a long editing session, or file permissions on the server. In our 17 Oct 2026 lab, a firewall rule and a stale check each gave a 403, and each cleared with its own fix.
Seeing this on your own site? Send us the address for a free site check, and a written report comes back within 2 business days.
Key points
- A 403 is a refusal, not a crash. Something read the request and decided to block it.
- In our lab a firewall rule blocked only the save that held a map embed. The same save went through once the rule was gone.
- A wrong or orphaned security check gave a 403 on the same save that went through with a fresh one. Reloading the editor gets a fresh one.
- If every page gives a 403, including the home page, look at the server first: file permissions and .htaccess.
On this page (9)
- What does a WordPress 403 Forbidden error mean?
- How did we test it?
- Why does saving a post give a 403?
- Why did a missing check give 401 and not 403?
- How do you fix a 403 Forbidden error in WordPress?
- What if the whole site shows 403?
- What did we not test?
- Is your site giving a 403 right now?
- Questions and answers
What does a WordPress 403 Forbidden error mean?
A WordPress 403 Forbidden error means a piece of your stack read the request and refused it. Nothing crashed. A crash is a 500.
The hard part is that four different layers can say no with the same number: the web server, a host or CDN firewall, a security plugin and WordPress itself. The fix depends on which one it was, so the first job is to find the layer.
Finding which layer blocked a request, on a staging copy so the live site keeps running, is part of our WordPress maintenance work.
How did we test it?
On 17 Oct 2026 we set up WordPress 7.1.3 on PHP 8.3.33 in WordPress Playground. We logged in as an admin through the normal login form and saved draft posts through the REST API, the same route the block editor uses.
For the firewall test we wrote a small stand-in file, not a real security plugin. It answers 403 to any save that holds an iframe tag, which is the kind of rule many firewalls carry against injected code. We sent every request with curl.
Why does saving a post give a 403?
Two of our tests broke the same save in two different ways.
With the firewall file in place, a plain draft saved with a 201. A draft holding a map embed got a 403 with the firewall’s own message, before WordPress saved anything. We removed the file and the same embed saved with a 201.
That is the pattern to look for. If only certain posts fail, and the ones that fail hold embeds, scripts or code samples, a rule is matching the content.
The second break was the security check, the nonce. The editor sends one with every save. A good nonce saved with a 201. A wrong one got a 403 with the code rest_cookie_invalid_nonce. When we dropped the login cookies, as happens when you log out in another tab, and sent the old nonce, that was a 403 too.
Why did a missing check give 401 and not 403?
A save with the login cookie but no nonce at all got a 401, not a 403.
The REST API authentication guide, read on 18 Oct 2026, explains it. Without a nonce, WordPress ignores the cookie and treats the request as logged out, so the answer is “who are you?” and not “no”. A wrong nonce is a refusal, so it is a 403.
Older admin screens use admin-ajax.php in place of the REST API. There a wrong nonce gave a 403 with a body of just -1, which matches the check_ajax_referer() reference.
How do you fix a 403 Forbidden error in WordPress?
Start with what fails, then go layer by layer:
- If only saving fails, copy your text, reload the editor and save again. The nonce handbook says a nonce lasts a day by default and 12 to 24 hours in practice, so an editor left open overnight carries a dead one.
- If only some posts fail, check the security plugin’s block log or the host’s firewall log at the time of the error. Allow the rule for that page or ask the host to, and do not switch the firewall off for good.
- If wp-admin or the login page fails, check for an IP block or a country block in the security plugin or the CDN.
- If every page fails, including the home page, look at the server.
When WordPress itself turns away a logged in user, that is a role problem. Our guide to the “Sorry, you are not allowed to access this page” message covers it.
What if the whole site shows 403?
Then the web server cannot or will not serve the files. The WordPress file permissions guide gives folders 755 or 750 and files 644 or 640, and never 777. Files copied over by a migration or a backup restore can arrive with other values, so check them first.
Also open .htaccess and look for Deny or Require lines that are not yours.
We do this as a single fix. On a staging copy we find the layer that blocks the request, change only that rule or setting, and hand back a site that saves and loads with the firewall still on.
What did we not test?
- Apache and nginx. Playground serves PHP itself, so file permissions and .htaccess deny rules could not be reproduced.
- A real security plugin, ModSecurity or a CDN firewall. The firewall rule was our stand-in.
- A nonce running out by time. We used a wrong nonce and one left over after the cookies were gone.
- The block editor screen itself. We sent the saves it sends.
Is your site giving a 403 right now?
Tell us which page or action gives the 403 and when it started, and we will say which layer is blocking it.
Want the rest of the site looked at too? Send your site address for the free site check, and a written reply comes within 2 business days. If the editor shows “not a valid JSON response” in place of the 403, our guide to the WordPress not valid JSON response error walks through that one.
Where did these facts come from?
- DistroCode lab, WordPress 7.1.3, PHP 8.3.33 (17 Oct 2026, 3:34 PM ET), REST saves with no, wrong, good and orphaned nonce, admin-ajax with a wrong nonce, lab firewall rule on and off, checked Oct 17, 2026
- WordPress REST API Handbook, Authentication (cookie logins need a wp_rest nonce; without one the request is treated as logged out), checked Oct 18, 2026
- WordPress developer reference, check_ajax_referer() (a failed check on an Ajax request ends with -1 and status 403), checked Oct 18, 2026
- WordPress Common APIs Handbook, Nonces (a nonce lasts one day by default, 12 to 24 hours in practice), checked Oct 18, 2026
- WordPress Advanced Administration Handbook, File permissions (folders 755 or 750, files 644 or 640, never 777), checked Oct 18, 2026
Questions and answers
Why do I get 403 Forbidden when saving a post in WordPress?
Most often a firewall rule matched something in the post, such as an embed or script code, or the editor's security check went stale. In our lab both gave a 403 on save while plain posts saved fine.
Can a security plugin cause a 403 error in WordPress?
Yes. Firewall rules answer 403 before WordPress saves anything. Check the plugin's block log for the time of the error, or pause the plugin briefly on a staging copy and try the same action again.
Why is my whole WordPress site showing 403 Forbidden?
When the home page and every other page give a 403, the server is refusing to read the files. Check the file and folder permissions and the .htaccess file before you look at plugins.
Rather hand this to us? See the WordPress maintenance plan Want to know if the problem stops here? Ask for the free site check.
We write up one real fix or build a few times a week on LinkedIn. Follow DistroCode there: linkedin.com/company/distrocode


