Python – Celery “Received unregistered task of type”


I have read quite a few posts that are similar to this but none seem to make sense to me.

I am trying to configure a Celery PeriodicTask to fire every 5 seconds but I'm getting hung up on a Celery configuration issue (I think)


import datetime
from celery.decorators import periodic_task

def send_queued_messages():
    # do something...


from comm.tasks import send_queued_messages
from datetime import timedelta
    'send_queued_messages_every_5_seconds': {
        'task': 'comm.tasks.send_queued_messages',   # Is the issue here?  I've tried a dozen variations!!
        'schedule': timedelta(seconds=5),

The relevant output from my error logs:

23:41:00 worker.1 | [2015-06-10 03:41:00,657: ERROR/MainProcess] Received unregistered task of type 'send_queued_messages'.
23:41:00 worker.1 | The message has been ignored and discarded.
23:41:00 worker.1 | 
23:41:00 worker.1 | Did you remember to import the module containing this task?
23:41:00 worker.1 | Or maybe you are using relative imports?
23:41:00 worker.1 | Please see for more information.
23:41:00 worker.1 | 
23:41:00 worker.1 | The full contents of the message body was:
23:41:00 worker.1 | {'utc': True, 'chord': None, 'args': [], 'retries': 0, 'expires': None, 'task': 'send_queued_messages', 'callbacks': None, 'errbacks': None, 'timelimit': (None, None), 'taskset': None, 'kwargs': {}, 'eta': None, 'id': 'a8ca18...227a56'} (216b)

Best Solution

I ran into this exact problem, and it turns out the issue is not with the name of the task, but that the Celery worker isn't aware of your task module.

In other words, you have the name of the task correct ('comm.tasks.send_queued_messages'), which was generated by the task decorator, you just haven't told Celery where to look for it.

The quickest solution is to add the following to myapp/

CELERY_IMPORTS = ['comm.tasks']

According to the docs, this determines the "sequence of modules to import when the worker starts."

Alternatively, you can configure your settings to auto discover tasks (see docs here), but then you would have to namespace your task module(s), moving comm/ to comm/comm/

For me, the confusion came from Celery's automatic naming convention, which looks like an import statement, which led me to believe I was using CELERYBEAT_SCHEDULE['task'] to tell Celery where to look for the task. Instead, the scheduler just takes the name as a string.