Troubleshooting

admin-ajax.php Errors and Timeouts: How to Find the Request That’s Failing

admin-ajax.php errors show up as spinning loaders, failed saves, and cart fragments that never update. How to trace the failing action and what the common culprits are.

admin-ajax.php Errors and Timeouts: How to Find the Request That’s Failing

admin-ajax.php is WordPress’s front door for asynchronous requests: cart fragments, form submissions, autosaves, builder saving, filter widgets. When it fails, the symptom is indirect — a spinner that never resolves, a cart that will not update, “Saving…” forever. The diagnosis is easier than it looks because every AJAX request identifies its action in plain sight.

Trace the failing request in 60 seconds

  1. Open the browser network tab (F12 → Network), trigger the broken behavior.
  2. Find the admin-ajax.php request — filter by “ajax”. Click it: the Payload tab shows action=the_action_name; the Response tab shows what came back: a 500 error body, a 0, a JSON error, or an HTML login page.
  3. Status codes mean different things: 400 — the action handler rejects the data (plugin bug or missing nonce); 500 — fatal error server-side (check debug.log, the line names the file); 403 — something blocked it: a security plugin’s firewall or mod_security; response is an HTML login page — session/nonce expired.

The common culprits, by symptom

  • Spinner forever on a form: the action’s handler fatals — the 500’s debug.log line names the plugin. One deactivation confirms.
  • Cart fragment not updating: cache plugin excluding or caching the AJAX call wrong — the cache-layer analysis is in the cache comparison.
  • Admin saves failing intermittently: Heartbeat throttling gone too aggressive (see the Heartbeat guide) or nonces expiring on long-lived tabs.
  • Everything AJAX fails after a migration: stale site URL in the database — AJAX posts to the old domain and gets CORS-blocked. The migration checklist covers the URL fix.
  • Timeouts on heavy actions: curl error 28-style timeouts inside plugins calling slow external APIs — the cURL timeout guide covers that pattern.

Deeper: Query Monitor

When the network tab is ambiguous, Query Monitor logs every AJAX request server-side with its timing and the hook that handled it — including which plugin registered the failing action. That last detail shortens the path from “something broke” to “this plugin’s handler” considerably.

Why does admin-ajax.php return 400?

The action handler rejected the request — missing/invalid nonce, malformed payload, or a plugin bug in the handler. The response body usually contains the specific error message.


Why is admin-ajax.php returning 403?

Something blocked it before WordPress: a security plugin's firewall rule, mod_security, or rate limiting. Whitelist the endpoint in the blocking layer, or the AJAX action in the plugin.


How do I find which plugin handles an AJAX action?

The network tab shows action=the_name in the payload; Query Monitor maps the action to the plugin that registered its handler. Then test with that plugin deactivated.


Why did AJAX break after moving my site?

Stale URLs: AJAX posts to the old domain and browsers block the cross-origin response. Search-replace the old URL in the database (wp search-replace) and clear caches.

The WPForge editorial team: WordPress and WooCommerce engineers with a decade of combined experience in store builds, speed optimization, migrations and plugin audits. Every guide is based on real client projects and hands-on testing, reviewed before publishing.

Revision history

  • October 2026 — Facts, version numbers and links re-verified against current vendor data.

We re-test and update our guides when tools change — see our editorial policy for how. Editorial policy →