The ajaxError event fires when a qualifying jQuery Ajax request completes with an error — not on success. This tutorial covers binding on document with .on("ajaxError"), the handler signature (event, jqXHR, ajaxSettings, thrownError), filtering by ajaxSettings.url, reading jqXHR.status and thrownError, opting out with global: false, and comparing global events with per-request .fail().
01
Global
AjaxEvent
02
document
Bind target
03
Errors
Fail only
04
settings
Filter URL
05
thrownError
Status text
06
Since 1.7
.on() API
Fundamentals
Introduction
When your page loads data with $.ajax(), $.get(), $.post(), or .load(), jQuery broadcasts lifecycle events to listeners on document. The ajaxError event is your global “something went wrong” hook — it fires only when a request fails, such as a 404 Not Found, a 500 server error, or a network timeout.
The official jQuery API distinguishes the ajaxErrorevent (bound with .on("ajaxError") since 1.7) from the deprecated .ajaxError()method used in older code. Unlike ajaxComplete, which runs for both success and failure, ajaxError is outcome-specific — successful requests trigger ajaxSuccess instead. On failed requests, ajaxError runs beforeajaxComplete.
Concept
Understanding the ajaxError Event
ajaxError is classified as an AjaxEvent — a global event triggered by jQuery’s Ajax transport, not a DOM event on a specific element. Whenever an Ajax request completes with an error, jQuery triggers ajaxError on document. Handlers receive four arguments: the native event object, the jqXHR object (same as the XMLHttpRequest wrapper returned by $.ajax()), ajaxSettings — the plain settings object used to create that request — and thrownError, the HTTP status text such as “Not Found” or “Internal Server Error.”
Every registered ajaxError handler runs for every failed qualifying request. To react only to certain URLs, inspect ajaxSettings.url inside the handler. Note: this handler is not called for cross-domain script or cross-domain JSONP requests.
💡
Beginner Tip
Bind once on $(document).on("ajaxError", fn) instead of adding a .fail() callback to every $.ajax() call when you need site-wide error logging or a global toast. Use global: false on requests that should not notify global listeners — for example, expected 404 checks or third-party widgets.
Foundation
📝 Syntax
The modern jQuery API for the ajaxError global event:
1. Bind a handler — $(document).on("ajaxError" [, handler]) (since 1.7)
jQuery
$( document ).on( "ajaxError", handler )
handler — function invoked when any qualifying Ajax request fails: function( event, jqXHR, ajaxSettings, thrownError ) { ... }.
event — the jQuery event object.
jqXHR — the jqXHR / XMLHttpRequest object; read jqXHR.status for the HTTP status code.
The old .ajaxError(handler) binding method still works but is deprecated. Migrate to $(document).on("ajaxError", handler) for consistency with other events and reliable unbinding via .off().
Return value
.on("ajaxError", handler) returns the jQuery object (document wrapped) for chaining.
Handler return values are ignored by jQuery’s global Ajax event system.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Bind global error handler
$(document).on("ajaxError", fn)
Handler signature
function(event, jqXHR, ajaxSettings, thrownError)
Read HTTP status code
jqXHR.status
Read status text
thrownError (4th argument)
Filter by URL
if (ajaxSettings.url === "/api/x")
Opt out of global events
$.ajax({ url: "/x", global: false })
Per-request error handling
$.ajax(...).fail(fn)
Remove handlers
$(document).off("ajaxError")
Compare
📋 ajaxError vs .fail() vs ajaxComplete
Three ways to react when an Ajax request fails — choose the scope and outcome that match your task.
ajaxError
global
Document event — runs for every qualifying failed request on the page
.fail()
per call
jqXHR callback — runs once for a single $.ajax() invocation that fails
ajaxComplete
all outcomes
Global event — fires after success or error; runs after ajaxError on failures
ajaxSuccess
2xx only
Global event — fires only when the request succeeds (not on error)
Global event order on a failed request: ajaxStart → ajaxSend → ajaxError → ajaxComplete → ajaxStop. On success, ajaxSuccess replaces ajaxError in step 3. ajaxStart and ajaxStop bracket the set of active global requests.
Hands-On
Examples Gallery
Examples 1, 3, and 4 follow the official jQuery API documentation. Examples 2 and 5 extend those patterns with URL filtering and a comparison with .fail(). Use the Try-it links to run each snippet in the browser.
📚 Official Patterns
Document-level handlers that observe every qualifying failed Ajax request.
Example 1 — Official Demo: Document Handler + .load() to Missing URL
Attach ajaxError on document, then trigger a failing Ajax request with .load() when the user clicks .trigger.
User clicks .trigger → .load() requests missing file
Request fails (404) → .log shows "Triggered ajaxError handler."
Successful .load() calls do NOT trigger ajaxError
How It Works
.load() is implemented with $.ajax() internally, so a failed fetch triggers global Ajax events. The ajaxError handler on document runs when the server returns an error or the resource is missing.
Example 2 — Filter by settings.url
All ajaxError handlers run for every failed request — use ajaxSettings.url to narrow the callback to one endpoint.
Failed request to ajax/missing.html → .log updated
Failed request to other URLs → handler runs but if-block skipped
Use settings.type, settings.context, or custom keys to filter further
How It Works
jQuery passes the same settings object used in $.ajax(settings) as the third argument. Compare settings.url (or a custom property you add to settings) before updating the DOM or logging.
Example 3 — Official Demo: Append Error Message to #msg
Show a message in the page whenever any Ajax request fails.
Each failing Ajax request → #msg gains " Error requesting page [url] "
Two parallel failures → two appended messages
Ideal for a simple error log or status strip
How It Works
Because ajaxError fires for every global failed request, appending to #msg builds a running error log. Pair with URL filtering if you only want messages for specific endpoints.
📈 Status Details & Per-Request Comparison
Read thrownError and jqXHR.status, and compare global vs per-request error handling.
Example 4 — Read thrownError and jqXHR.status
Inspect the HTTP status code and status text when a request fails.
404 request → Status: 404 — Not Found
500 request → Status: 500 — Internal Server Error
thrownError is the status text; jqXHR.status is the numeric code
How It Works
On HTTP errors, jQuery passes the status text as thrownError and the numeric code on jqXHR.status. Use both for user-friendly error messages and logging.
Example 5 — Compare Global ajaxError Counter vs Per-Request .fail()
One global handler increments a page-wide counter; each $.ajax() call uses .fail() for its own error callback. Successful requests do not trigger ajaxError.
Click #run-fail → two failing $.ajax() calls
globalError → +2 (one ajaxError per failed request)
perRequestFail → +2 (one .fail() per call)
Success request → ajaxError unchanged; .fail() not called
How It Works
ajaxError centralizes cross-cutting error concerns (toasts, analytics). .fail() keeps error handling next to the call site — show a row-specific message, re-enable one button, etc. Only failed requests trigger ajaxError.
Applications
🚀 Common Use Cases
Error logging — append failed URL and status to a debug panel for every Ajax error during development.
Global toast notifications — show a user-friendly “Something went wrong” banner when any request fails, filtered by settings.url.
Analytics hooks — send error timing, URL, and jqXHR.status to monitoring when ajaxError fires.
Session expiry detection — watch for 401/403 responses globally and redirect to login.
Third-party isolation — set global: false on widget requests so expected failures do not trigger your global ajaxError logic.
Testing — assert that a test harness saw the expected number of failed requests via a global counter.
🧠 Global Ajax Event Order (Failed Request)
1
ajaxStart
First active global request begins — show a page-wide loading indicator.
ajaxStart
2
ajaxSend
Just before the request is sent — last chance to modify headers globally.
ajaxSend
3
ajaxError
Request failed — all registered ajaxError handlers execute with thrownError.
ajaxError
4
ajaxComplete
Always runs after step 3 — cleanup hook for success or error.
ajaxComplete
5
👉
ajaxStop
Last active global request finished — hide the loading indicator.
Important
📝 Notes
Bind with $(document).on("ajaxError", handler) since jQuery 1.7 — not the deprecated .ajaxError(handler) method.
Since jQuery 1.9, attach global Ajax handlers to document — not window.
ajaxError fires only on failure — successful requests trigger ajaxSuccess instead.
On failed requests, ajaxError runs beforeajaxComplete.
Every registered handler runs for every failed qualifying request.
Requests with global: false do not trigger ajaxError.
Not called for cross-domain script or cross-domain JSONP requests.
Read the HTTP code with jqXHR.status and the status text from thrownError.
Differentiate requests with ajaxSettings.url, ajaxSettings.type, or custom settings properties.
For per-request error handling, prefer $.ajax(...).fail(fn) over a global handler with heavy filtering.
Compatibility
Browser Support
The ajaxError event is a jQuery global Ajax event — not a native DOM event. It works wherever jQuery’s Ajax transport runs: all browsers supported by your jQuery version. Bind with .on("ajaxError") since 1.7; attach handlers to document since 1.9.
✓ jQuery 1.7+
jQuery ajaxError event
Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. Requires jQuery Ajax — requests made with fetch() or axios do not trigger jQuery global events.
100%With jQuery Ajax
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
ajaxErrorUniversal
Bottom line: Safe in any jQuery project using $.ajax(), $.get(), $.post(), or .load(). Prefer .on('ajaxError') over deprecated .ajaxError().
Wrap Up
Conclusion
The jQuery ajaxError event is the global “request failed” hook — it runs when any qualifying Ajax call completes with an error. Bind handlers on document with .on("ajaxError", fn), inspect ajaxSettings to filter by URL, and read jqXHR.status plus thrownError for error details.
Remember the event order on failures: ajaxError first, then ajaxComplete, then ajaxStop when no global requests remain. Use global: false to opt out. For logic tied to one call, chain .fail() on the jqXHR instead of growing a global handler.
Filter with ajaxSettings.url when the handler should not run for every failed request
Pair with ajaxStart / ajaxStop for loading indicators
Use global: false for silent background or expected-failure requests
Remove handlers with $(document).off("ajaxError") on SPA teardown
❌ Don’t
Attach global handlers to window — use document since jQuery 1.9
Use deprecated .ajaxError(handler) in new code
Assume ajaxError fires on success — use ajaxSuccess or ajaxComplete
Rely on ajaxError for cross-domain script or JSONP requests
Duplicate per-request .fail() logic inside a global handler without filtering
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about ajaxError
Global, errors only, on document.
6
Core concepts
doc01
document
Bind here
Global
✗02
Errors
Fail only
Behavior
url03
settings
Filter
ajaxSettings
40404
thrownError
Status text
4th arg
off05
global:false
Opt out
Private
.on06
.on()
Not .ajaxError()
Modern
❓ Frequently Asked Questions
ajaxError is a global Ajax event (AjaxEvent) that fires whenever a qualifying jQuery Ajax request completes with an error — HTTP failures, transport errors, or parser errors. Bind handlers with $(document).on('ajaxError', handler) since version 1.7. Every registered handler runs for every failed request.
Since jQuery 1.9, all global Ajax event handlers — including ajaxError — must be bound to document, not window or other elements. Use $(document).on('ajaxError', fn) and $(document).off('ajaxError', fn) to remove them.
No. ajaxError runs only when a request fails. Successful responses trigger ajaxSuccess instead. Both are followed by ajaxComplete, which fires for success and error alike. Use ajaxError for global error logging; use ajaxSuccess when you only care about successful responses.
ajaxError is a global document event — one handler observes every qualifying failed request on the page. fail() is per-request on the jqXHR returned by $.ajax() — it runs only for that single call. Use global events for site-wide error UI; use fail() for request-specific error handling.
When $.ajax() or $.ajaxSetup() sets global: false, that request opts out of all global Ajax events. ajaxError will not fire for it. Per-request fail() and always() callbacks still run normally.
The fourth handler argument, thrownError, receives the textual portion of the HTTP status when an HTTP error occurs — for example "Not Found" for 404 or "Internal Server Error" for 500. Pair it with jqXHR.status (the numeric code) for complete error details.
Did you know?
jQuery fires ajaxError for every registered handler — if three functions listen on document, all three run when one request fails. That differs from per-request .fail(), which runs only for the jqXHR it was chained to. On a failed request, ajaxError always runs before ajaxComplete. Cross-domain script and JSONP requests never trigger ajaxError.