jQuery Deferred fail() Method

Beginner
6 min read
Updated: Oct 2026
4 examples
Live preview

What Is fail()?

deferred.fail(failCallbacks) adds handlers that run when a Deferred is rejected (failure). Available since jQuery 1.5. It returns the Deferred so you can chain more methods.

Remember
dfd.fail(fn)
dfd.fail(fn1, fn2)
dfd.fail([fn1, fn2], fn3)

reject("err")  → fail handlers run with "err"
resolve(...)   → fail does NOT run

$.get(url).fail(fn)  // jqXHR error
NeedUse
On failuredfd.fail(fn)
On successdfd.done(fn)
Either outcomedfd.always(fn)

How to Use fail()

Create or receive a Deferred/Promise, attach fail, then reject (or wait for AJAX to fail).

  1. Get a Deferred (e.g. $.Deferred()) or a jqXHR from $.ajax / $.get.
  2. Call .fail(function (reason) { ... }) — pass a function or an array of functions.
  3. When failure happens, call reject(reason) (or let AJAX fail).
  4. Handlers run in order with the reject arguments; chain done / always as needed.
PieceRequired?Role
Deferred / jqXHRYesObject that can reject
failCallbacksYesFunction or array of functions
Return value—Same Deferred (chainable)

Pseudocode

Pseudocode
function fail(deferred, callbacks):
    queue = flatten(callbacks)   // functions and arrays
    add each callback to failure list

    when deferred.reject(args...):
        for each fn in failure list (in order):
            fn(args...)

    return deferred              // chainable

Cheat Sheet

Keep these facts handy while wiring error handlers.

TopicDetail
Syntaxdeferred.fail(failCallbacks [, failCallbacks ])
SincejQuery 1.5 (catch alias since 3.0)
Runs whenDeferred is rejected
ArgumentsSame values passed to reject / rejectWith
Multiple handlersFunctions or arrays; order preserved
Late attachIf already rejected → runs immediately
ReturnsThe Deferred (chainable)

Live Preview

Pick a scenario and see how fail() behaves on reject.

Browser demo of deferred.fail() — same ideas as the examples below.

Result
fail: Network error

jQuery Examples

Short, copy-ready snippets. Open DevTools Console, or use Try It Yourself for a live editor.

Example 1 — Basic Error Handler

Attach fail(), then reject() with a reason.

jQuery
var dfd = $.Deferred();

dfd.fail(function (error) {
  console.log("fail: " + error);
});

dfd.reject("Network error");
// fail: Network error
Try It Yourself

How It Works

  1. Create. $.Deferred() starts in the pending state.
  2. Register. fail(fn) queues the error callback.
  3. Reject. reject("Network error") settles as failure.
  4. Run. The handler receives that string and logs it.

Example 2 — Multiple Handlers

Pass functions or arrays; they run in registration order (per the API docs).

jQuery
var dfd = $.Deferred();
var lines = [];

function logErr(msg) { lines.push("log: " + msg); }
function showErr(msg) { lines.push("ui: " + msg); }
function track(msg) { lines.push("track: " + msg); }

dfd.fail([logErr, showErr], track);

dfd.reject("timeout");
console.log(lines.join(" | "));
// log: timeout | ui: timeout | track: timeout
Try It Yourself

How It Works

  1. Arrays allowed. [logErr, showErr] adds both callbacks in order.
  2. Extra args. track also receives "timeout".
  3. Order. Handlers fire in the order they were added.
  4. Split work. Logging, UI, and analytics stay in separate functions.

Example 3 — Multiple Reject Arguments

reject can pass several values — same shape as jqXHR .fail(xhr, status, error).

jQuery
var dfd = $.Deferred();

dfd.fail(function (xhr, status, error) {
  console.log(status);       // error
  console.log(error);        // Not Found
  console.log(xhr.status);   // 404
});

dfd.reject({ status: 404 }, "error", "Not Found");
Try It Yourself

How It Works

  1. Multi-arg reject. jQuery forwards every argument to each fail callback.
  2. AJAX shape. Real $.ajax().fail often gets (jqXHR, textStatus, errorThrown).
  3. Parameter list. Match them left-to-right in your handler.
  4. Tip. Read status / error for messages; inspect xhr for status codes.

Example 4 — Late Registration

If the Deferred is already rejected, a new fail() still runs right away.

jQuery
var dfd = $.Deferred();

dfd.reject("already failed");

dfd.fail(function (error) {
  console.log("fail (late): " + error);
});
// fail (late): already failed
Try It Yourself

How It Works

  1. Settle first. reject happens before any handler is attached.
  2. Attach late. fail(fn) sees the Deferred is already rejected.
  3. Immediate call. jQuery invokes fn with the stored rejection reason.
  4. Why it matters. Modules can attach listeners safely at different times.

Edge Cases & Pitfalls

Check these before relying on fail() alone.

path

No success coverage

fail() never runs on resolve. Always pair with done() or a fulfillment branch on then().

alias

catch needs jQuery 3+

catch() is an alias for fail() since 3.0. Stick with fail() if you still support jQuery 1.x / 2.x.

chain

fail vs then chaining

fail() returns the same Deferred. Prefer then(null, onRejected) or catch() when you need to recover and continue a promise chain.

once

Settled only once

A Deferred rejects or resolves once. Extra reject calls are ignored; late fail handlers still see the first reason.

Browser Support

deferred.fail() has shipped since jQuery 1.5 and works in all modern browsers with jQuery loaded. It is part of the Deferred Object API (also used by jqXHR). catch() as an alias needs jQuery 3.0+.

✓ jQuery 1.5+

deferred.fail()

Supported everywhere jQuery Deferred runs in the browser. Use it for error callbacks on Deferred and AJAX objects.

100% Browser support
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
fail() Excellent

Bottom line: Call dfd.fail(fn) for errors. Pair with done() for success. Works on Deferred and jqXHR since jQuery 1.5.

Performance Notes

ApproachCostBest for
dfd.fail(fn)O(k) handlersError-only side effects
dfd.catch(fn)O(k) (alias)Promise-style naming (3+)
dfd.always(fn)O(k)Shared cleanup

Handler cost is usually tiny compared with the async work (network, timers). Prefer clear success/error separation over micro-optimizing callback count.

Key Takeaways

  • Role: error callbacks when a Deferred is rejected.
  • Multi: pass functions or arrays; order is preserved.
  • Pair: use done() / always() for success and cleanup.
  • Alias: catch() ≡ fail() in jQuery 3+.

One line: dfd.fail(fn) runs on reject only — queue error work, and pair with done() for the success path.

Frequently Asked Questions

fail() registers one or more callbacks that run when the Deferred is rejected (failure). Handlers receive the values passed to reject() or rejectWith(), in registration order.
fail() runs only on reject. done() runs only on resolve. Pair them (or use then with two callbacks) so you cover both outcomes.
In jQuery 3.0+, catch() is an alias for fail() on Deferred and Promise objects. They behave the same — catch() exists for Promise-style naming.
Yes. Pass functions or arrays of functions. Callbacks run in the order they were added. You can also chain .fail().fail().
Yes. If the Deferred is already rejected, new fail() handlers fire immediately with the rejection reason.
Yes. jqXHR objects support .fail(function(xhr, status, error) { ... }) — the classic jQuery AJAX error-handler pattern.

Next: isRejected()

Check whether a Deferred has already been rejected.

isRejected() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful