Jump to solution
Verify

The Fix

pip install celery==5.4.0

Based on closed celery/celery issue #8678 · PR/commit linked

Production note: This usually shows up under retries/timeouts. Treat it as a side-effect risk until you can verify behavior with a canary + real traffic.

Jump to Verify Open PR/Commit
@@ -2271,6 +2271,8 @@ def link_error(self, errback): applied to the body. """ + errback = maybe_signature(errback) + if self.app.conf.task_allow_error_cb_on_chord_header:
repro.py
from celery import Celery, chain, chord, signature, group app = Celery( "celery_bug", backend="redis://0.0.0.0:6479/", broker="redis://0.0.0.0:6479/" ) app.conf.task_allow_error_cb_on_chord_header = True @app.task(bind=True) def orig_task(self, arg): chord_headers = group([chord_header.s(arg=f"arg{i}") for i in range(5)]) replacement_chord = chord(chord_headers, chord_body.s()) return self.replace(replacement_chord) @app.task def chord_header(arg): return f"header: {arg}" @app.task def chord_body(arg): return f"body: {arg}]" @app.task def handle_error(*args, **kwargs): print(f"handle error called with args {args} kwargs {kwargs}") def main(): print(f"hello world") res = orig_task.apply_async(args=["spam"], link_error=handle_error.s()) print(f"RESULT: {res.get()}") if __name__ == "__main__": main()
verify
Re-run: poetry run python celery_bug.py
fix.md
Option A — Upgrade to fixed release\npip install celery==5.4.0\nWhen NOT to use: Do not use this fix if your application relies on dict type errbacks in a different context.\n\n

Why This Fix Works in Production

  • Trigger: $ poetry run python celery_bug.py
  • Mechanism: Fixed a bug where chord.link_error() throws an exception on a dict type errback object, resolving the issue.
  • Why the fix works: Fixed a bug where chord.link_error() throws an exception on a dict type errback object, resolving the issue. (first fixed release: 5.4.0).
Production impact:
  • If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.

Why This Breaks in Prod

  • Shows up under Python 3.8 in real deployments (not just unit tests).
  • Surfaces as: $ poetry run python celery_bug.py

Proof / Evidence

  • GitHub issue: #8678
  • Fix PR: https://github.com/celery/celery/pull/8702
  • First fixed release: 5.4.0
  • Reproduced locally: No (not executed)
  • Last verified: 2026-02-09
  • Confidence: 0.85
  • Did this fix it?: Yes (upstream fix exists)
  • Own content ratio: 0.26

Discussion

High-signal excerpts from the issue thread (symptoms, repros, edge-cases).

“Thank you for the bug report! Bugfix merged to main”
@Nusnus · 2023-12-07 · confirmation · source
“previous related fix https://github.com/celery/celery/pull/8463”
@auvipy · 2023-11-28 · source

Failure Signature (Search String)

  • $ poetry run python celery_bug.py

Error Message

Stack trace
error.txt
Error Message ------------- $ poetry run python celery_bug.py hello world Traceback (most recent call last): File "celery_bug.py", line 39, in <module> main() File "celery_bug.py", line 35, in main print(f"RESULT: {res.get()}") File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/celery/result.py", line 251, in get return self.backend.wait_for_pending( File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/celery/backends/asynchronous.py", line 223, in wait_for_pending return result.maybe_throw(callback=callback, propagate=propagate) File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/celery/result.py", line 365, in maybe_throw self.throw(value, self._to_remote_traceback(tb)) File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/celery/result.py", line 358, in throw self.on_ready.throw(*args, **kwargs) File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/vine/promises.py", line 235, in throw reraise(type(exc), exc, tb) File "/Users/robertgalloway/Library/Caches/pypoetry/virtualenvs/rpg-play-aJQQ1jqR-py3.8/lib/python3.8/site-packages/vine/utils.py", line ... (truncated) ...

Minimal Reproduction

repro.py
from celery import Celery, chain, chord, signature, group app = Celery( "celery_bug", backend="redis://0.0.0.0:6479/", broker="redis://0.0.0.0:6479/" ) app.conf.task_allow_error_cb_on_chord_header = True @app.task(bind=True) def orig_task(self, arg): chord_headers = group([chord_header.s(arg=f"arg{i}") for i in range(5)]) replacement_chord = chord(chord_headers, chord_body.s()) return self.replace(replacement_chord) @app.task def chord_header(arg): return f"header: {arg}" @app.task def chord_body(arg): return f"body: {arg}]" @app.task def handle_error(*args, **kwargs): print(f"handle error called with args {args} kwargs {kwargs}") def main(): print(f"hello world") res = orig_task.apply_async(args=["spam"], link_error=handle_error.s()) print(f"RESULT: {res.get()}") if __name__ == "__main__": main()

Environment

  • Python: 3.8

What Broke

Tasks failed with an AttributeError when using chords with dict type errbacks.

Fix Options (Details)

Option A — Upgrade to fixed release Safe default (recommended)

pip install celery==5.4.0

When NOT to use: Do not use this fix if your application relies on dict type errbacks in a different context.

Use when you can deploy the upstream fix. It is usually lower-risk than long-lived workarounds.

Fix reference: https://github.com/celery/celery/pull/8702

First fixed release: 5.4.0

Last verified: 2026-02-09. Validate in your environment.

Get updates

We publish verified fixes weekly. No spam.

Subscribe

When NOT to Use This Fix

  • Do not use this fix if your application relies on dict type errbacks in a different context.

Verify Fix

verify
Re-run: poetry run python celery_bug.py

Did This Fix Work in Your Case?

Quick signal helps us prioritize which fixes to verify and improve.

Prevention

  • Make timeouts explicit and test them (unit + integration) to avoid silent behavior changes.
  • Instrument retries (attempt count + reason) and alert on spikes to catch dependency slowdowns.

Version Compatibility Table

VersionStatus
5.4.0 Fixed

Related Issues

No related fixes found.

Sources

We don’t republish the full GitHub discussion text. Use the links above for context.