# Buggy code
def _call_task_errbacks(self, request, exc, traceback):
    old_signature = []
    for errback in request.errbacks:
        errback = self.app.signature(errback)
        if (
            # Celery tasks type created with the @task decorator have
            # the __header__ property, but Celery task created from
            # Task class do not have this property.
            # That's why we have to check if this property exists
            # before checking is it partial function.
            hasattr(errback.type, "__header__")
            and
            # workaround to support tasks with bind=True executed as
            # link errors. Otherwise retries can't be used
            not isinstance(errback.type.__header__, partial)
            and arity_greater(errback.type.__header__, 1)
        ):
            errback(request, exc, traceback)
        else:
            old_signature.append(errback)
    if old_signature:
        # Previously errback was called as a task so we still
        # need to do so if the errback only takes a single task_id arg.
        task_id = request.id
        root_id = request.root_id or task_id
        group(old_signature, app=self.app).apply_async(
            (task_id,), parent_id=task_id, root_id=root_id
        )


# Traceback (KeyError)
# TaskProducer:
from celery import Signature
Signature(
'export.hello', args=['homer'],
link_error=Signature('msg.err', queue='msg')
).apply_async()

# ExportWorker:
[2017-05-09 00:14:53,458: INFO/MainProcess] Received task: export.hello[ad4ef3ea-06e8-4980-8d9c-91ae68c2305a]
[2017-05-09 00:14:53,506: INFO/PoolWorker-1] Resetting dropped connection: us-west-2.queue.amazonaws.com
[2017-05-09 00:14:53,517: INFO/PoolWorker-1] Starting new HTTPS connection (9): us-west-2.queue.amazonaws.com
[2017-05-09 00:14:53,918: WARNING/PoolWorker-1] /vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py:542: RuntimeWarning: Exception raised outside body: Task of kind 'msg.err' never registered, please make sure it's imported.:
Traceback (most recent call last):
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 367, in trace_task
R = retval = fun(*args, **kwargs)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 622, in __protected_call__
return self.run(*args, **kwargs)
File "/vagrant/test_worker/app/tasks.py", line 9, in hello
raise Exception("NO HOMERS ALLOWED!")
Exception: NO HOMERS ALLOWED!

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/vagrant/test_worker/env/src/kombu/kombu/utils/objects.py", line 42, in __get__
return obj.__dict__[self.__name__]
KeyError: 'type'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 381, in trace_task
I, R, state, retval = on_error(task_request, exc, uuid)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 323, in on_error
task, request, eager=eager, call_errbacks=call_errbacks,
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 157, in handle_error_state
call_errbacks=call_errbacks)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/trace.py", line 202, in handle_failure
call_errbacks=call_errbacks,
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/backends/base.py", line 168, in mark_as_failure
self._call_task_errbacks(request, exc, traceback)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/backends/base.py", line 174, in _call_task_errbacks
if arity_greater(errback.type.__header__, 1):
File "/vagrant/test_worker/env/src/kombu/kombu/utils/objects.py", line 44, in __get__
value = obj.__dict__[self.__name__] = self.__get(obj)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/canvas.py", line 490, in type
return self._type or self.app.tasks[self['task']]
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/registry.py", line 19, in __missing__
raise self.NotRegistered(key)
celery.exceptions.NotRegistered: 'msg.err'

exc, exc_info.traceback)))
[2017-05-09 00:14:53,996: INFO/MainProcess] Resetting dropped connection: us-west-2.queue.amazonaws.com
[2017-05-09 00:14:53,999: INFO/MainProcess] Starting new HTTPS connection (3): us-west-2.queue.amazonaws.com
[2017-05-09 00:14:54,237: ERROR/MainProcess] Pool callback raised exception: Task of kind 'msg.err' never registered, please make sure it's imported.
Traceback (most recent call last):
File "/vagrant/test_worker/env/src/kombu/kombu/utils/objects.py", line 42, in __get__
return obj.__dict__[self.__name__]
KeyError: 'type'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/vagrant/test_worker/env/lib/python3.5/site-packages/billiard/pool.py", line 1748, in safe_apply_callback
fun(*args, **kwargs)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/worker/request.py", line 366, in on_failure
self.id, exc, request=self, store_result=self.store_errors,
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/backends/base.py", line 168, in mark_as_failure
self._call_task_errbacks(request, exc, traceback)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/backends/base.py", line 174, in _call_task_errbacks
if arity_greater(errback.type.__header__, 1):
File "/vagrant/test_worker/env/src/kombu/kombu/utils/objects.py", line 44, in __get__
value = obj.__dict__[self.__name__] = self.__get(obj)
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/canvas.py", line 490, in type
return self._type or self.app.tasks[self['task']]
File "/vagrant/test_worker/env/lib/python3.5/site-packages/celery/app/registry.py", line 19, in __missing__
raise self.NotRegistered(key)
celery.exceptions.NotRegistered: 'msg.err'

# (MessageWorker has no output)

# Fixed code
def _call_task_errbacks(self, request, exc, traceback):
    old_signature = []
    for errback in request.errbacks:
        errback = self.app.signature(errback)
        if not errback._app:
            # Ensure all signatures have an application
            errback._app = self.app
        try:
            if (
                # Celery tasks type created with the @task decorator have
                # the __header__ property, but Celery task created from
                # Task class do not have this property.
                # That's why we have to check if this property exists
                # before checking is it partial function.
                hasattr(errback.type, "__header__")
                and
                # workaround to support tasks with bind=True executed as
                # link errors. Otherwise retries can't be used
                not isinstance(errback.type.__header__, partial)
                and arity_greater(errback.type.__header__, 1)
            ):
                errback(request, exc, traceback)
            else:
                old_signature.append(errback)
        except NotRegistered:
            # Task may not be present in this worker.
            # We simply send it forward for another worker to consume.
            # If the task is not registered there, the worker will raise
            # NotRegistered.
            old_signature.append(errback)

    if old_signature:
        # Previously errback was called as a task so we still
        # need to do so if the errback only takes a single task_id arg.
        task_id = request.id
        root_id = request.root_id or task_id
        group(old_signature, app=self.app).apply_async(
            (task_id,), parent_id=task_id, root_id=root_id
        )