NewTry MagicWP now - first month free
WordPress troubleshooting

The REST API encountered an error

Something answered the request that was not WordPress, or answered it with HTML. The editor stops working first, because it depends on the API for everything.

The REST API encountered an error: The REST API request failed due to an error.

Short answer

Request a REST route directly and look at what comes back. JSON means the API is alive and the problem is authentication; an HTML error page means something in front of WordPress intercepted the route before PHP answered.

Diagnosis

What causes it, most likely first.

Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.

CauseHow to checkFix
A security plugin or WAF blocks the routeThe request returns HTML or a 403 from something that is not WordPress, and the block is logged by the plugin or firewall rather than by WordPress.Allow /wp-json/ for authenticated users. Rules written to stop user enumeration frequently block the whole namespace rather than the one endpoint they were aimed at.
Permalinks are broken so the route never resolvesThe pretty route 404s while the query-string form answers correctly. That difference isolates it to rewrite rules.Flush the rewrite rules. The REST route is a rewrite like any other, so it disappears when they are stale.
The Authorization header is strippedUnauthenticated routes work and authenticated ones report that you are not logged in, even though you are.Pass the Authorization header through to PHP at the web server. CGI-style setups drop it by default, and application passwords stop working entirely when they do.
A plugin emits output before the JSONThe response is valid JSON with something in front of it — a notice, a stray blank line — which makes it unparseable.Find the plugin printing early. The same stray output usually also breaks feeds and produces a headers-already-sent warning elsewhere.
Walkthrough

Fixing it, step by step.

Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.

  1. Ask the API for the index

    This route requires no authentication, so anything other than JSON is the answer.

    curl -sS -i https://example.com/wp-json/ | head -n 20
  2. Compare pretty and plain routing

    If the second works and the first does not, rewrite rules are the problem and nothing else needs testing.

    curl -sS -o /dev/null -w '%{http_code}\n' 'https://example.com/wp-json/wp/v2/types'
    curl -sS -o /dev/null -w '%{http_code}\n' 'https://example.com/?rest_route=/wp/v2/types'
  3. Rebuild the rewrite rules

    Cheap, safe, and fixes a surprising share of these.

    wp rewrite flush --hard
  4. Confirm the Authorization header survives

    Add this to the web server or .htaccess when authenticated routes are the only ones failing.

    # .htaccess
    SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
    
    # nginx + fastcgi
    fastcgi_param HTTP_AUTHORIZATION $http_authorization;
  5. Bisect plugins if it is still failing

    Test the route between each deactivation rather than at the end, so the plugin that fixes it is unambiguous.

    wp plugin deactivate --all
    curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/wp-json/
On MagicWP

What the platform takes off the list.

Nothing sits between the request and WordPress that rewrites or inspects /wp-json/, so the route reaches PHP intact and the header arrives with it — the two causes that account for most of these. Permalink rules are part of the site's own configuration rather than a shared file other sites also edit, so they do not go stale when something unrelated is deployed.

FAQ

Questions, answered.

Can I just disable the REST API?
Not really. The block editor, Site Health, application passwords and much of wp-admin are built on it, so disabling it breaks the admin rather than securing it. Restricting specific routes to authenticated users is the reasonable version of that idea.
The editor says “Updating failed” — is that the same problem?
Usually yes. The editor saves through the REST API, so a blocked or malformed response surfaces there first, and this page's checks are the right ones to run.
Why does it work when I am logged out but not logged in?
That points at the Authorization header or the cookie nonce rather than at routing. Unauthenticated routes never needed either, which is why they keep working.
Is a 404 on /wp-json/ different from a 403?
Yes, and usefully so. A 404 means the route was not found, which is rewrite rules. A 403 means something found it and refused, which is a security rule.
Related

If that was not it.

These fail in ways that look similar from the browser.