Error guide / The REST API encountered an error

The REST API encountered an error

WordPress talks to itself over its own REST API: the block editor saves posts through it, and Tools > Site Health tests it by making the server request its own address /wp-json/wp/v2/types/post?context=edit as a logged-in administrator. This notice means that request came back as something other than normal JSON: a 403, a 404, a 500, a timeout, or a response with extra output mixed into it. Site owners and editors see it in Site Health, usually together with "Updating failed. The response is not a valid JSON response." in the editor. Almost every guide on this answers with "deactivate your plugins one by one", and you can skip that: what your site returns to an outside request already narrows the cause to one of four situations, and the check on this page gives you that answer in a few seconds.

Check your site

>

What causes it

Most often the request is blocked before it ever reaches WordPress: a security plugin with a "disable REST API" option, a firewall rule at the host (on shared hosting this is usually ModSecurity), or Cloudflare's WAF and bot protection. Next most common are broken rewrite rules, where the site itself works but /wp-json/ returns 404, which typically follows a migration, an .htaccess edit, or an nginx config without the right try_files. A PHP fatal error or memory exhaustion in a plugin that hooks into rest_api_init produces a 500. The rarest case is also the most stubborn: the API answers perfectly from the outside and only the server's request to itself fails, because of local DNS, an outbound firewall, HTTP auth on a staging site, or a host that refuses connections from its own IP.

How to fix it

  1. Run the check on this page against https://yoursite.com/wp-json/wp/v2/ and read the status code: 200 means the API answers the outside world, 403 means something is blocking it, 404 means the route or the rewrite rules are gone, and 500 means PHP is failing inside WordPress. Look at the final URL and the Server header too, because an unexpected redirect or a Server value of cloudflare tells you who else is in the path.
  2. Before you change anything the check points at, take a full backup of the files and the database, since the likely fixes touch .htaccess, plugin settings and firewall rules on a live site and you want a way back.
  3. If you got 403, the request never reached WordPress: turn off any "disable REST API" or REST hardening option in your security plugin (Wordfence, Solid Security and similar all have one), ask your host to check the ModSecurity log for your IP at the minute you ran the check, and in Cloudflare open Security > Events, find the rule matching /wp-json/ and add a skip rule for that path.
  4. If you got 404, open the URL in a browser: a JSON body containing rest_no_route means WordPress answered and a plugin or code snippet removed the routes, while an HTML 404 page means the rewrite rules are broken. For the second case go to Settings > Permalinks and press Save without changing anything to rebuild them; if https://yoursite.com/?rest_route=/wp/v2/ returns JSON while /wp-json/ still 404s, the missing piece is the WordPress rewrite block in .htaccess or the try_files line in your nginx config.
  5. A 401 with a JSON body such as {"code":"rest_not_logged_in"} is not the failure: the API is alive and simply asking for a login, which is normal on routes that require one, so look for a membership, maintenance or password-protection layer that extends this to every route. A 500 is a real failure inside PHP, so read your host's PHP error log for the fatal or the memory exhaustion line and fix or deactivate the plugin it names.
  6. If the check returns 200, open the same URL in a browser and look at what comes before the opening brace: a PHP warning, stray HTML or a blank line from a BOM in wp-config.php or a plugin file produces the "did not behave correctly" variant, and that file has to be cleaned. If the JSON is clean, the public API is fine and only the server's loopback request fails, so send your host the exact Site Health wording, which names the cURL error (for example "cURL error 28: Operation timed out"), and ask them to confirm the server can reach its own domain over HTTPS.

Related errors