---
title: "Fix \"Updating failed\" and \"Publishing failed\" in WordPress"
url: https://wpministry.co/errors/updating-failed/
description: "The block editor saves through the REST API, and the answer was not the JSON it expects. Nothing already saved is lost. What came back instead shows the fix."
lang: en-US
---

Skip to content

# How to fix "Updating failed" and "Publishing failed" in the WordPress editor

The block editor saves through the site's REST API. "Updating failed" means the answer to that request was not the JSON the editor expects. Nothing already saved is lost. Look at what came back instead of JSON, and the fix follows from it.

By

WP Ministry

Published

October 7, 2026

Tested on

WordPress 7.1.4, PHP 8.3.36

## In short

- Nothing already saved is lost. The change on your screen is not saved yet, so copy it before you reload.
- The editor saves through the REST API, at /wp-json/. The message means the answer was not JSON.
- Open /wp-json/ in a browser tab. A 404 there means the rewrite rules are missing.
- The browser's Network panel shows the failed request's status and what came back. That tells the causes apart.
- A 403 comes from a security plugin or a firewall, and the rule is theirs to change.

The block editor saves by sending your changes to the site's REST API, at an address that begins `/wp-json/`, and it expects the answer in a data format called JSON. "Updating failed." or "Publishing failed." means the save did not go through. When the notice ends "The response is not a valid JSON response.", something did answer, but not with JSON: a 404 page, a firewall's block page, or the right answer with a PHP message printed in front of it.

Nothing that was already saved is lost. The change on your screen is not saved yet, and it exists only in that browser tab.

## Keep what you wrote

Do not reload the page or close the tab. Click the three dots in the editor's top toolbar, then choose "Copy all blocks". The editor answers "All content copied." Paste it into a text file on your computer, and paste it back into the post once saving works.

## Find out what came back

Three checks, quickest first.

**Open the REST API yourself.** In a new tab, go to `https://example.com/wp-json/`, with your own domain. A screen of text that begins with `{` is JSON, and the address works. A 404 page means the first fix. If your permalinks are set to Plain, the address is `https://example.com/?rest_route=/` instead.

**Ask Site Health.** Go to Tools, then Site Health. "The REST API is available" among the passed tests means the server reached its own API. "The REST API encountered an error" or "The REST API encountered an unexpected result" opens to show the address it tried and the response it got. The server makes this test on itself, so it can pass while requests from your browser still fail.

**Read the failed request.** Open your browser's developer tools and click the Network tab. It records only while it is open, so save again. Click the request that failed, read its status, then open its Response tab.

| What the request shows | Use |
| --- | --- |
| Status 404 and a "not found" page | The first fix |
| Text ahead of the first `{` that names a `.php` file and a line | The second fix |
| An address that differs from the one in your address bar | The third fix |
| Status 403, or a page that says the request was blocked | The fourth fix |
| Anything else | The fifth fix |

If the notice ends "Could not get a valid response from the server." instead, the browser got no answer at all. Start with the third fix.

## Where it goes wrong

A page request passes through each of these in turn. This one comes from **WordPress itself**.

1. Browser
2. DNS
3. HTTPS
4. CDN or firewall
5. Web server
6. PHP
7. WordPress (this error comes from here)
8. Database and files

## What causes it

- ### The REST API address answers 404
  Common
  With pretty permalinks the editor saves to an address that begins /wp-json/. That address exists only inside WordPress, so it depends on the rewrite rules in .htaccess. When they are missing, the web server answers with its own 404 page.
  Fix: Get /wp-json/ answering again
- ### A PHP message is printed in front of the answer
  Sometimes
  A warning or notice printed into the response comes out ahead of the JSON, and the two together are not JSON. WordPress hides such messages from the editor's requests, so one that gets through was printed before WordPress had loaded or by code that turns display back on.
  Fix: Stop PHP printing messages into the answer, or Switch off the plugin that breaks the answer
- ### The site's address settings do not match the address in your browser
  Sometimes
  The editor sends its requests to an address built from the Site Address setting. When that is not the address you are working at, http in place of https or another form of the domain, the request goes somewhere other than the page it came from. A browser blocks an http request made from an https page.
  Fix: Make the site's address match the one you work at
- ### A security plugin or a firewall refuses the request
  Sometimes
  A firewall compares each request with general patterns of attack. A post that contains HTML or code can match one by mistake, and the request is refused before WordPress can answer it.
  Fix: Find what refused the request and have the rule changed
- ### A plugin or the theme breaks the answer
  Sometimes
  A plugin or theme that prints anything of its own while WordPress is answering leaves the editor with something other than the JSON it asked for.
  Fix: Switch off the plugin that breaks the answer

## How to fix it

### Get /wp-json/ answering again

- Easy
- Low risk
- About 5 minutes
- Steps tested on WordPress 7.1.4

These steps are for Apache, which reads `.htaccess`.

1. #### Step 1: Open Settings, then Permalinks
   Change nothing on the screen.
2. #### Step 2: Press Save Changes
   WordPress writes its rules into `.htaccess` again. "Permalink structure updated." means it could. If it tells you to update `.htaccess` yourself, it could not write to the file.
3. #### Step 3: Open /wp-json/ again
   Text that begins with `{` means the address is back. Return to the editor and save.

With WP-CLI, a hard flush does the same, but only once WP-CLI has been told the server has `mod_rewrite`. Put this in `wp-cli.yml`, in the folder you run WP-CLI from:

wp-cli.yml

```
apache_modules:
  - mod_rewrite
```

Then run:

bash

```
wp rewrite flush --hard
```

Without that file, the command rebuilds WordPress's list of addresses and leaves `.htaccess` alone. A hard flush works on a single site only, not on a multisite network.

If WordPress cannot write the file, or the 404 stays, 404 errors on posts and pages that exist (https://wpministry.co/errors/404-not-found/) has the rules to paste in by hand and what to ask of a server that ignores them. It is the same fault: posts answer 404 there for the reason `/wp-json/` does here.

### Stop PHP printing messages into the answer

- Takes care
- Back up first
- About 10 minutes
- Steps tested on WordPress 7.1.4

WordPress never displays PHP errors on REST API requests, whatever `WP_DEBUG_DISPLAY` is set to. A message that reaches the editor anyway was printed before WordPress had loaded, from `wp-config.php` on a server whose PHP is set to display errors, or by code that turns display back on.

1. #### Step 1: Read the message
   It is the text ahead of the first `{` in the Response tab. It says what PHP objected to, and names a file and a line. Write both down.
   If the file is inside `wp-content/plugins/` or `wp-content/themes/`, use the fifth fix. If it is `wp-config.php`, carry on.
2. #### Step 2: Turn display off at the top of wp-config.php
   Put this on a line of its own, directly under the opening `<?php`:
   It has to come first. A message caused by a line above it has already been printed.
   wp-config.php Copy

   ```
   ini_set( 'display_errors', 0 );
   ```

3. #### Step 3: Save the file and save the post again
   If the post saves, the message was the cause.
4. #### Step 4: Correct the line the message named
   Turning display off hides the message. It does not put right what PHP objected to. Open the file at that line and correct it, or ask whoever added the line.

PHP's own manual says error display is for development and should never be on for a site on the internet, and advises logging in its place. Ask your host where the PHP error log is. If your hosting panel has a PHP settings page, switch `display_errors` off there as well: that covers every file.

**To undo it:** Remove the line from wp-config.php.

### Make the site's address match the one you work at

- Takes care
- Back up first
- About 15 minutes
1. #### Step 1: Compare the addresses
   Look at the address bar while you edit. Then go to Settings, then General, and read "WordPress Address (URL)" and "Site Address (URL)". Compare the start of each: http or https, and whether www comes before the domain.
2. #### Step 2: Look at where the failed request went
   The editor builds the address of each request from the Site Address. In the Network panel, if the failed request's address starts differently from the one in your address bar, the settings are the cause. A browser blocks an http request made from an https page outright.
3. #### Step 3: Correct the two settings
   How to change your WordPress URL without locking yourself out (https://wpministry.co/blog/change-wordpress-url/) covers changing the two addresses, and how to get back in if a wrong one shuts you out.

If both settings already say https and requests still go to http, a proxy or CDN in front of the site is hiding https from WordPress. Mixed content warnings (https://wpministry.co/errors/mixed-content/) has the lines for `wp-config.php` that correct it.

### Find what refused the request and have the rule changed

- Takes care
- No risk
- About 20 minutes
1. #### Step 1: Confirm the refusal
   In the Network panel, a refused request has status 403, which means the server understood it and would not process it. Its Response tab holds a block page in place of JSON. Read it: a block page that names a product tells you whose rule it is.
2. #### Step 2: Try a post with one plain sentence
   Add a new post, type one sentence and save it as a draft. If that saves, something in the first post's content matches a firewall rule. HTML, and text that reads like code or a database query, are what such rules match by mistake.
3. #### Step 3: Look in the security plugin's log
   If a security plugin with a firewall is active, open its log of blocked requests and find the one made when you saved. Allowing it is done in that plugin's own settings.
4. #### Step 4: Ask the host
   If no plugin blocked it, look to a firewall on the server or one in front of the site. Send the host the time, the address of the failed request and your IP address. Ask which rule refused it, and whether it can be relaxed for your site.

Do not leave a firewall switched off to get a post saved. 403 Forbidden (https://wpministry.co/errors/403-forbidden/) covers a security plugin that has blocked your own address, and what to send the host.

### Switch off the plugin that breaks the answer

- Takes care
- Low risk
- About 15 minutes
- Steps tested on WordPress 7.1.4
1. #### Step 1: Start with the plugin the response named
   A PHP message with a path through `wp-content/plugins/` names the plugin's folder straight after it.
2. #### Step 2: Switch it off
   On the Plugins screen, deactivate it.
3. #### Step 3: Save the post again
   If it saves, that plugin was the cause. Update it, or report the message to its author.

With WP-CLI, use the plugin's folder name:

bash

```
wp plugin deactivate plugin-folder-name
```

If the response names no plugin, the cause has to be found by removal. How to find and fix a WordPress plugin conflict (https://wpministry.co/blog/fix-wordpress-plugin-conflicts/) covers switching every plugin off and bringing them back in halves, a mode that does this for your login only, and checking the theme.

**To undo it:** Activate the plugin again.

## When to get help

If /wp-json/ answers with JSON in a browser tab, the failed request carries no PHP message, and saving still fails with every plugin switched off, whatever is refusing the save sits between your browser and WordPress. Finding it means reading the server's and the firewall's logs, which on most hosting only the host can open.

## Common questions

Site Health says the REST API is available. Why does saving still fail?

Site Health's test is a request from the server to itself. Yours travels from your browser, through any firewall or proxy in front of the site, and carries the content of your post. It can be refused where the server's own request is not. Go by the Network panel.

Why does it fail on one post and not on others?

Something in that post's content matches a firewall rule: HTML or code, for example. Use the fourth fix. A new post with one plain sentence that saves confirms it.

Does turning WP_DEBUG_DISPLAY on cause this?

Not by itself. WordPress switches error display off for requests that ask for JSON, as the editor's do. A page opened in a browser tab asks for HTML, so with debugging on, `/wp-json/` opened in a tab can show messages the editor never receives. Trust the Response tab of the failed request.

## More on this subject

- WordPress errors and troubleshooting: https://wpministry.co/topics/wordpress-troubleshooting/
- Guide WordPress uptime monitoring: what a check sees and what it misses: https://wpministry.co/blog/wordpress-uptime-monitoring/
- Guide How to update the PHP version of a WordPress site: https://wpministry.co/blog/update-php-version-wordpress/
- Glossary term Permalink: https://wpministry.co/glossary/permalink/
- Glossary term PHP memory limit: https://wpministry.co/glossary/php-memory-limit/
- Glossary term REST API: https://wpministry.co/glossary/rest-api/
- Guide Slow WordPress admin: how to find the cause and fix it: https://wpministry.co/blog/slow-wordpress-admin/

## Would you rather we fixed it?

Quick Fix is $49. One issue, one site, up to about an hour. No fix, no fee. 30-day warranty.

More about this work: One-time WordPress fix (https://wpministry.co/services/one-time-fix/)

May we measure how this site is used?

A yes notes the pages of this visit and loads Google Analytics. A no keeps and loads nothing. See the cookies page (https://wpministry.co/legal/cookies/).

If you say yes, we note the pages you look at during this visit and load Google Analytics. If you say no, nothing is kept and nothing is loaded. The site works the same either way. The cookies page (https://wpministry.co/legal/cookies/) has the details.

## Structured data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://wpministry.co/#organization",
      "name": "WP Ministry",
      "url": "https://wpministry.co/",
      "logo": "https://wpministry.co/brand/logo.png",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "1309 Coffeen Ave STE 1200",
        "addressLocality": "Sheridan",
        "addressRegion": "WY",
        "postalCode": "82801",
        "addressCountry": "US"
      },
      "sameAs": [
        "https://www.linkedin.com/company/wp-ministry/",
        "https://x.com/wpministryco",
        "https://www.instagram.com/wpministryco/",
        "https://www.facebook.com/wpministryco",
        "https://www.tiktok.com/@wpministryco",
        "https://www.pinterest.com/wpministryco/",
        "https://www.youtube.com/channel/UCOZRuAukk5QSTRPG6BaHl3Q"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://wpministry.co/#website",
      "name": "WP Ministry",
      "url": "https://wpministry.co/",
      "inLanguage": "en-US",
      "publisher": {
        "@id": "https://wpministry.co/#organization"
      }
    },
    {
      "@type": "TechArticle",
      "@id": "https://wpministry.co/errors/updating-failed/#article",
      "headline": "How to fix \"Updating failed\" and \"Publishing failed\" in the WordPress editor",
      "description": "The block editor saves through the REST API, and the answer was not the JSON it expects. Nothing already saved is lost. What came back instead shows the fix.",
      "url": "https://wpministry.co/errors/updating-failed/",
      "mainEntityOfPage": "https://wpministry.co/errors/updating-failed/",
      "inLanguage": "en-US",
      "image": "https://wpministry.co/og/errors/updating-failed.png",
      "author": {
        "@id": "https://wpministry.co/#organization"
      },
      "publisher": {
        "@id": "https://wpministry.co/#organization"
      },
      "datePublished": "2026-10-07T00:00:00.000Z",
      "dateModified": "2026-10-07T00:00:00.000Z"
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://wpministry.co/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Error fixes",
          "item": "https://wpministry.co/errors/"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "How to fix \"Updating failed\" and \"Publishing failed\" in the WordPress editor"
        }
      ]
    }
  ]
}
```