Web Development18 min read

WordPress Invalid JSON Response: Fix Publishing and Updates

The error describes a failed response, not its cause. Preserve your draft, inspect the actual save request, then distinguish a session problem, missing route, firewall challenge or PHP output before changing settings.

Ali RehmanAli RehmanFreelance Web Developer
Published
Woman working at a desk with a laptop and two computer monitors
On this page 13 sections

You finish editing a WordPress page and click Update. The editor responds with Updating failed. The response is not a valid JSON response. A new post may show Publishing failed instead. The public website can still look normal, which makes the failure harder to understand: visitors are reading pages, but the editor cannot confirm the write you just requested.

The shortest useful answer: protect your unsaved work, inspect the failing save request in your browser's Network panel, and read its response. A login page, firewall challenge, missing REST route and PHP warning require different fixes. Do not change every plugin, URL or security setting merely because they can all produce a similar banner.

This guide is for a WordPress site you own or administer. It covers block-editor publishing and updating, plus the related image-upload case. It does not assume your database is damaged or that the post definitely failed to save. If WordPress reports a successful save but visitors still see old content, start with WordPress changes not showing instead. That is a different investigation.

What the invalid JSON message actually means

JSON is a structured data format used between the editor and the server. When the block editor saves a standard post, it commonly makes a REST API request such as POST /wp-json/wp/v2/posts/123. The number identifies the post; your actual request may use a different path for pages, custom post types, autosaves or plugin features. The official Posts reference documents the create, retrieve and update routes.

The key word in the message is response. The editor expected usable data back. Instead, it may have received an HTML login screen, a security challenge, a server-generated error page or text mixed into a JSON document. The banner alone cannot tell you which layer produced that response. A problem in the request can cause the server to reject it, but the visible JSON message does not prove that your article text is malformed JSON.

  • HTTP success is not save confirmation. A 200 response can contain an HTML page. Read the body and verify the saved content.
  • Valid JSON can still describe a failed action. A 403 response with a WordPress error code is different from a 403 HTML block page.
  • No readable response is another branch. A failed connection, blocked request or CORS error may produce a transport error rather than a JSON parsing error. Check what the browser actually recorded.

The upstream WordPress response-parser source makes these distinctions visible. For this guide, 14 synthetic response cases were checked against that pinned utility. Those checks demonstrate parsing behavior, not a repair on a customer's WordPress installation. The exact error wording and empty-body handling can differ between WordPress builds and plugins.

1. Protect the draft and check whether it saved

Before refreshing, keep a private local copy of the unsaved text. In the block editor, Copy all blocks or the Code editor can help preserve block markup as well as words; menu labels vary by version. Also note changes to the title, featured image, excerpt, categories and custom fields. A text copy does not back up every setting. Do not paste confidential drafts into a public JSON validator or an unfamiliar online debugging tool.

Keep the original editor tab open. In a second tab, open the post list or the saved post for the same ID and compare it with your intended version. Check the content itself, not only a modified timestamp. A server can accept a write and then return an unusable response, leaving the editor uncertain about the result. Repeatedly clicking Publish can repeat plugin hooks, notifications or other side effects even when it does not create a second post.

  1. 1Record which action failed: Save draft, Publish, Update, autosave or Upload. Note the time and timezone.
  2. 2Check whether the intended content is present in a fresh view of the saved post, without replacing the unsaved original tab.
  3. 3Identify the scope: one post, all posts, one account, one browser, images only, or a problem that began after a known change.
  4. 4Use an isolated staging copy for repeated tests, with outbound email, payment and automation integrations disabled. On production, inspect an action you intended to perform instead of repeatedly sending test writes.

If you cannot reach the dashboard at all, use the WordPress login recovery guide first. A backup is important before configuration changes, but restoring an old production database is not a routine JSON fix: it can replace newer orders, submissions and accounts.

2. Inspect the request that failed

Open Developer Tools, choose Network, and enable Preserve log before the next intended save. In Chrome or Edge, use Fetch/XHR to reduce the list, then look at the requests that occur when the banner appears. The Chrome Network reference explains the Method column and the Headers, Payload and Response tabs. If the filter hides the relevant request, return to All; not every editor or upload flow uses the same mechanism.

  1. 1Select the request associated with the failing action. Match its method, path and time; a successful autosave beside a failed Update request is not the same result.
  2. 2In Headers, record the status, request URL and Content-Type. Check whether the request was redirected to another host, scheme, path or login screen.
  3. 3In Response, read the beginning of the body. Look for JSON fields such as code and message, an HTML document, a PHP warning, a challenge page or an empty response.
  4. 4Inspect request details locally only as needed. Record the presence of the session and nonce, not their secret values. If no response is available, note the browser's exact network or Console error.
Do not use Edit and resend or Copy as fetch to replay a production save. Observe the request first. Raw HAR files and copied cURL commands can contain cookies, nonces, private post content and authorization data. Even a sanitized HAR can retain sensitive URLs or payloads. Share only reviewed, redacted evidence through your host's approved support channel.

An apostrophe, an HTML tag or a quote in a normal post does not automatically break JSON. The editor's request handler normally serializes the data. If a particular block triggers the problem, investigate the response to that content and any validation or security rule involved. Deleting punctuation from an article is not a general repair.

3. Match the response to the right fix

Use the following branches as a decision guide. Status codes narrow the search, but do not identify the responsible plugin or host on their own. Compare the response body with the event or application logs for the same request before changing configuration.

Close-up of a developer typing on a laptop in front of computer monitors
Check the actual response alongside the failing request. This contextual photograph shows a development workspace, not a screenshot of a WordPress error or a client incident.

HTML login page or a redirect to another address

A response starting with <!doctype html>, login markup or a branded access page is not the expected post data. Check the final URL and any recorded redirect. A WordPress login, a hosting password gate, an SSO page and a CDN challenge are different sources of HTML; the page's appearance and the request trace help distinguish them.

Confirm that you can sign in through the normal authorized route in another tab. After securing your unsaved work, reopen the editor from the correct HTTPS address. If the REST request points to an old domain or a different hostname, investigate URL configuration rather than repeatedly clearing cookies. Keep staging password protection in place and ask the host to configure the legitimate editor and loopback paths properly.

401 or 403 with a WordPress JSON error

Read the code and message fields. The REST authentication documentation explains that dashboard cookie authentication also requires a REST nonce, normally sent as X-WP-Nonce. With no nonce, WordPress treats this cookie-authenticated request as unauthenticated, even if you appear logged in elsewhere. The account still needs permission to perform the requested action.

{
  "code": "rest_cookie_invalid_nonce",
  "message": "Cookie check failed",
  "data": { "status": 403 }
}

That is valid JSON describing an authentication failure. WordPress's cookie-check implementation associates an invalid REST nonce with this 403 error. Preserve your draft, confirm the current login and reload the editor safely. The API client can attempt nonce refresh itself; if the error persists, inspect that refresh request and whether a cache, proxy or login layer is returning the wrong response.

A capability error such as rest_cannot_edit calls for a permissions check on that post, not a blanket firewall exception. Compare the account's intended role, post ownership and plugin restrictions with an authorized working case. Do not grant Administrator to every editor or remove nonce checks. An Application Password is not a routine fix for a broken dashboard session.

403, 406 or an HTML firewall challenge

A host firewall or CDN can reject a legitimate request before WordPress creates its normal response. Check security events for the same timestamp, path, method and request ID. A 403 alone does not prove a firewall caused it: WordPress permissions can produce 403 too. A 406 can be another clue to investigate, not a universal ModSecurity diagnosis.

For Cloudflare, the documented Challenge Page indicator is cf-mitigated: challenge. Challenge responses use text/html, even when the requested resource was an API response. If those headers are present, use the matching security event to determine why that request was challenged.

Ask the host or security administrator to review the exact matching rule and intended editor operation. A fix may involve a narrowly scoped rule adjustment, a corrected plugin request or an authenticated route policy. Keep authentication and unrelated protections active. Do not disable the whole firewall or allow every request to /wp-json/; that path contains many different operations, including those added by plugins.

404: missing REST route or rewrite failure

An HTML 404 page and a JSON rest_no_route response are not identical. An HTML page suggests the request may have missed the intended API handling. A WordPress JSON error means an API handler responded, but the requested route and method were not matched. Inspect the exact path and HTTP method rather than assuming that every 404 needs the same rewrite rule.

Use the API root advertised by your installation. The REST discovery reference documents the https://api.w.org/ Link relation and the equivalent page-head link. Depending on permalink configuration, the root can use /wp-json/ or a ?rest_route=/ query. A subdirectory installation can have a different base path. Do not paste a root-domain example over the route your site actually needs.

On a standard root installation, comparing the read-only API index at https://example.com/wp-json/ with https://example.com/?rest_route=/ can help investigate rewrites. A working query route and failing pretty route point toward routing configuration, but a working index does not prove authenticated POST requests succeed. Use your own confirmed base URL; example.com here is a placeholder, not a diagnostic service.

If the evidence points to stale WordPress rewrite rules, record the existing permalink structure and back up relevant configuration. Re-saving that same structure can refresh WordPress rules. Do not switch a live site's public URLs to a different format as a casual experiment. Apache, Nginx and managed hosts handle routing differently; deleting the entire .htaccess file can also remove unrelated access rules. Follow the permalink troubleshooting guide or have the host inspect the active server configuration.

500, 502 or 503: PHP and server failures

Match the failure to the host's application, PHP and proxy logs. A PHP fatal error, upstream failure, resource limit or maintenance response can all interrupt an editor request, but the status is not a complete diagnosis. Note whether every save fails or only a larger post, image operation or plugin-specific action does. Use the log for that request, not an unrelated warning from yesterday.

Unexpected output can also corrupt an otherwise useful JSON body. A warning, debugging echo, var_dump or other output before the JSON object makes the combined response invalid. The following is a deliberately synthetic example, not an instruction to add debug output:

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

Warning: illustrative unexpected output
{"id":123}

The JSON-looking suffix does not make the whole body valid JSON.

The WordPress debugging handbook distinguishes logging from displaying errors. Prefer host logs or an isolated staging environment. If temporary debugging is needed, keep error display off, store logs in a protected location and remove temporary logging afterward. A public debug.log can expose sensitive paths and data. Hiding warnings is not the complete repair: fix the code or configuration producing the unexpected output. The critical-error guide covers safe recovery when the application itself is failing.

200 with an empty, truncated or unexpected body

Read the complete response, not just its Content-Type. A header saying application/json does not make HTML or a truncated object valid. Conversely, a parser may read a JSON body even when its header is incorrectly text/plain. That does not make the server configuration correct. In the controlled tests for this guide, both cases were checked separately.

The tested development-branch parser accepts an exactly empty successful body as null and treats 204 as no content; whitespace-only and truncated JSON responses fail parsing. Other builds can behave differently. None of these empty responses proves that the intended post was saved. A JSON string or unrelated object can parse successfully too. Verify the expected post record and fresh saved content, not merely the absence of a JSON exception.

No response: connection, certificate or browser blocking

If Network shows a failed connection, certificate error, mixed-content block or CORS error without a readable body, start with that failure. It is not evidence that the server returned malformed JSON. Check the exact request origin, HTTPS certificate, browser extension behavior and recent proxy changes. Compare another browser without disabling its security protections. Never solve an editor request by allowing insecure content or turning off TLS verification.

If only one post or one block fails

When a simple draft works and one page fails, start with what differs. It could be the content, payload size, a particular block, post permissions, registered metadata or a plugin route. This pattern makes a site-wide outage less likely, but does not prove that the global configuration is perfect or that your writing contains invalid JSON.

  1. 1On isolated staging, reproduce the problem with a copy of the affected post and the same intended role. Keep the original content intact.
  2. 2Compare the successful and failing request paths, methods, statuses and response bodies. A block-specific endpoint needs its own investigation.
  3. 3For a content-dependent failure, remove or add blocks in halves on the copy, narrowing the smallest example that changes the outcome. Also check custom fields and attached assets; body text is not the only input.
  4. 4Correlate the minimal example with security or application logs. Preserve the test result and restore the complete intended content after a targeted fix.

Do not permanently strip embeds, punctuation or useful content simply to hide the symptom. A content-triggered firewall event needs rule review; a valid JSON validation error needs the relevant field or plugin fixed; a fatal error needs code-level investigation. If longer posts fail with a 413 or a size-related log, review request limits with the host instead of raising memory or upload values arbitrarily.

If the error happens while uploading an image

Distinguish the upload request from the later post save. The REST Media reference documents POST /wp/v2/media, while other WordPress upload paths can use an admin upload endpoint. Inspect the request your interface actually made. Uploading through Media Library can exercise a different path; success there narrows the issue but does not prove the original editor upload route is repaired.

  • Every small, supported image fails: compare session, route and security evidence before assuming the file is too large.
  • Only large files fail: compare byte size, request limits and the exact response. A 413 points toward a request-size restriction at some layer; determine which layer imposed it.
  • The upload starts but processing fails: inspect PHP/image-processing logs, available resources and storage. Pixel dimensions and compressed file size are different constraints.
  • Only one file fails: test an authorized non-sensitive copy with a simple filename and a genuinely supported format. Changing an extension is not image conversion.

Check the library before retrying: an attachment may exist even if the editor did not process its response. Avoid creating repeated copies. After a fix, verify the attachment, generated sizes and insertion into the post. If uploading works but the public page shows a missing image, continue with WordPress images not showing. That is downstream of the JSON response problem.

After an HTTPS change or migration

Compare the editor address with the failing REST request and its final destination. Look for an old domain, an HTTP request from an HTTPS editor, an unexpected www change or a lost subdirectory. Confirm the intended configuration before editing Settings. A valid certificate on the homepage does not prove that a request to a different hostname is configured correctly.

The WordPress General Settings reference distinguishes WordPress Address, where the application lives, from Site Address, the public site location. They can legitimately differ when WordPress has its own directory. Configuration constants can override those fields. Do not force both addresses to match or remove an override without checking what value would become active.

Behind a reverse proxy, WordPress must correctly recognize the original HTTPS request through a trusted configuration. The HTTPS handbook describes this requirement. Ask the host to inspect the actual proxy and origin path; do not trust arbitrary forwarded headers or copy old server examples without matching your installation. For a repeating redirect, use the WordPress redirect-loop guide. Clearing a cache cannot repair contradictory routing rules.

Why a passing Site Health test is not enough

Tools > Site Health can expose REST errors, loopback problems and configuration clues. Record its exact result and time. However, the REST availability implementation makes a server-side GET request to the post-type endpoint with context=edit. It is not the same request as your browser posting a specific article body to a save endpoint.

An index or health check can pass while a firewall blocks POST, one content pattern, a particular account or a plugin route. The reverse can happen too: a host's loopback path can fail while an external browser request works. Use Site Health to add evidence, not to dismiss the failing request. Do not remove site protection simply to turn its result green.

Test plugins and themes without disrupting the site

If the response or change history implicates a plugin, theme or custom snippet, reproduce the same failure on staging. Start with the recently changed component or feature. Change one variable, repeat the same authorized test and restore it if the result does not support the hypothesis. Record versions and the smallest reproducible example for the maintainer.

A controlled all-plugins/default-theme baseline can help on an isolated copy, but it is not an appropriate first experiment on a live store. Payment, membership, forms and scheduled integrations can stop working. Normal plugin deactivation also does not remove must-use plugins, drop-ins, host rules or a CDN. If the error remains, that does not prove all extension or infrastructure code is innocent.

Switching to Classic Editor may avoid the affected workflow temporarily, but it does not demonstrate that the REST issue is fixed. Converting complex blocks can change their behavior or content. Preserve the original, test compatibility on staging and return to the intended editor to verify the actual repair.

4. Prove the repair and prevent a repeat

Repeat the operation that originally failed under the same conditions. A blank test post cannot verify a fix for a failing embed or large image. A different account cannot verify the original editor's permissions. Keep security controls enabled and test the affected route rather than only the homepage.

Two women reviewing a laptop screen together in an office
Verify the saved content and repeat the original workflow after a fix. The people in this contextual stock photograph are not the article's author or a claimed client team.
  1. 1Confirm the intended request reaches the correct HTTPS host and route without an unexpected login page or challenge.
  2. 2Inspect the successful response for the expected post ID and status. Match the response to the save action, not a neighboring autosave or media request.
  3. 3Open a fresh view of the saved post and verify a specific intended change. For published content, check the public version separately and account for caching.
  4. 4Retest the affected post, account, block or media case. Remove temporary debug output, close temporary exceptions and confirm the required security rules remain in place.
  5. 5Record the cause, exact change and a small regression check for the next plugin update, deployment or migration.

If WordPress now saves correctly but the public page remains old, investigate the relevant cache layer rather than reopening the JSON diagnosis. If the post is scheduled for later, its intended status and publication time need separate checks; the missed-schedule guide covers that path.

A support note your host can act on

Escalate when you cannot inspect the relevant server configuration, a production change would affect customer access, or the logs point to code outside your control. A concise evidence note is more useful than an admin password or an unreviewed network export. Fill this in locally and send only the necessary redacted details:

Site and affected editor action:
First noticed, time and timezone:
Scope: all posts / one post / one account / uploads only
Recent deployment, plugin, URL or hosting change:
Request method and path (remove tokens):
Status and final destination:
Response type: JSON error / HTML / empty / network failure
JSON error code, if present:
Redacted request ID or matching host event:
Does a fresh view show the intended saved change?
Staging reproduction and changes already reversed:

Do not include passwords, cookies, nonces, private post bodies or raw HAR files.

For a targeted investigation, WordPress development and fixes can cover custom code, REST requests and editor behavior. Website maintenance can cover update testing and recurring checks. Share the public URL and a redacted symptom summary to discuss the scope; do not send credentials through the contact form.

Frequently asked questions

Why does WordPress say publishing failed when the page exists?

The server may have accepted the write before the editor received an unusable response, or the page may show an older saved version. Keep your unsaved work and compare the exact post ID and intended content in a fresh view before retrying. A page existing is not proof that the latest change saved.

Will saving permalinks fix every invalid JSON response?

No. Re-saving the existing structure can help when stale rewrite rules prevent the REST route from being handled. It does not repair an expired session, missing capability, firewall challenge or PHP output. Use the failing request to decide whether routing is the relevant branch, and preserve the current public URL structure.

Why does only one post return the JSON error?

Compare its request, content, size, permissions, metadata and blocks with a working case. A security rule or plugin can react to one specific input. Reproduce on a copy, isolate the smallest difference and check the matching response or log; do not assume ordinary punctuation makes post content invalid JSON.

Can I disable the REST API to remove the error?

No. The block editor relies on REST operations, so disabling them can make editing worse and affect other integrations. Repair the blocked or malformed response while preserving authentication, nonces and the permissions required for each operation.

Should I install a JSON-fixer plugin or use Classic Editor?

There is no single plugin that can correctly repair every cause. Another plugin adds a variable before you know whether the failure is routing, authentication, security or application code. Classic Editor can be a temporary, compatibility-tested workaround, not proof that the original REST workflow is repaired.

Does this error mean my SEO or database is broken?

The message is not a Google penalty or a database diagnosis. It concerns a response during an editor operation. A broader server outage may affect public pages too, but inspect those pages separately. Repairing publishing restores a workflow; it does not guarantee Google indexing, rankings or traffic.

Sources, tests and review scope

Prepared on 31 October 2026 with AI-assisted research and editing, checked against the linked WordPress, Chrome and Cloudflare documentation. The controlled lab executed the pinned WordPress response-parser utility against 14 synthetic responses, with only its translation function stubbed. It did not run a complete WordPress installation, test a customer's firewall or verify a live save. Empty-response behavior is specific to the tested source version.

The photographs are licensed stock images of people at work, used for context rather than as WordPress screenshots. They are not pictures of this site's author or clients, and no endorsement is implied. The response examples are synthetic; interface labels and installed plugins can vary.

Written by

Ali Rehman - Freelance Web Developer

I work on WordPress websites, practical fixes and scoped web applications. Read my background and skill scope, or send a project brief to discuss a written plan and quote - start here.

More articles by Ali Rehman →