#10195·celery

New-style errbacks in `_call_task_errbacks` are called with no exception handling — one failing errback silently halts the rest

Author: tejas-aeCreated Mar 13, 2026Updated Sep 17, 2026

In celery/backends/base.py, _call_task_errbacks handles two errback styles. New-style errbacks (those with __header__ and arity > 1) are invoked directly with no surrounding try/except:

python
# celery/backends/base.py, lines ~252-265
try:
    if (
        hasattr(errback.type, '__header__') and
        not isinstance(errback.type.__header__, partial) and
        arity_greater(errback.type.__header__, 1)
    ):
        errback(request, exc, traceback)   # <-- no exception handling
    else:
        old_signature.append(errback)
except NotRegistered:
    old_signature.append(errback)          # only NotRegistered is caught

If a new-style errback raises any exception other than NotRegistered, that exception propagates uncaught, and subsequent errbacks in the chain are never called.

Compare with old-style errbacks (lines ~275-288), which do wrap execution in a try/except to log and continue.

Impact:

  • A bug in errback A silently prevents errback B from running
  • The exception may bubble up to the backend internals, causing unpredictable state
  • There is no log entry indicating which errback failed

Questions:

  1. Is the missing exception handling in the new-style path an oversight, or is it intentional (i.e. new-style errbacks are trusted to be safe)?
  2. Should new-style errbacks be wrapped in the same defensive try/except as old-style ones, with an error log on failure?
  3. Is there a test covering the case where a new-style errback raises an unexpected exception?

File: celery/backends/base.py, lines 244–288.