celery/celery · critical · ImproperlyConfigured

Cannot mix new and old setting keys, please rename the foll

Error message

Cannot mix new and old setting keys, please rename the
following settings to the new format:

{renames}

What it means

Raised in celery/app/utils.py:274 as ImproperlyConfigured when the user's settings simultaneously contain both new-style (lowercase, e.g. `task_serializer`) and old-style (UPPERCASE prefixed, e.g. `CELERY_TASK_SERIALIZER`) keys without a clean rename. Celery's Settings loader detects the mix, picks the majority namespace, and emits a rename suggestion list (`{renames}`). The message lists exactly which keys to rename. The guard prevents ambiguous/partial config where two keys collide.

Source

Thrown at celery/app/utils.py:274

            info, left = _old_settings_info, is_in_new
        if is_in_new and len(is_in_new) > len(is_in_old):
            # Majority of the settings are new
            info, left = _settings_info, is_in_old
    else:
        # no settings, just use new format.
        info, left = _settings_info, is_in_old

    if prefix:
        # always use new format if prefix is used.
        info, left = _settings_info, set()

    # only raise error for keys that the user didn't provide two keys
    # for (e.g., both ``result_expires`` and ``CELERY_TASK_RESULT_EXPIRES``).
    really_left = {key for key in left if info.convert[key] not in have}
    if really_left:
        # user is mixing old/new, or new/old settings, give renaming
        # suggestions.
        raise ImproperlyConfigured(info.mix_error.format(renames='\n'.join(
            FMT_REPLACE_SETTING.format(replace=key, with_=info.convert[key])
            for key in sorted(really_left)
        )))

    preconf = {info.convert.get(k, k): v for k, v in preconf.items()}
    defaults = dict(deepcopy(info.defaults), **preconf)
    return Settings(
        preconf, [conf, defaults],
        (_old_key_to_new, _new_key_to_old),
        deprecated_settings=is_in_old,
        prefix=prefix,
    )


class AppPickler:
    """Old application pickler/unpickler (< 3.1)."""

    def __call__(self, cls, *args):

View on GitHub (pinned to 3511be41db)

Solutions

  1. Read the `{renames}` list in the error message and rename every listed key to the suggested new name.
  2. Search the config (and env) for the exact old keys reported and remove/replace them.
  3. Use the `configuration_url`/new-format docs for your Celery version to verify all keys are lowercase new-style.

Example fix

// before
CELERY_TASK_SERIALIZER = 'json'
task_result_expires = 3600
// after
task_serializer = 'json'
task_result_expires = 3600
Defensive patterns

Strategy: validation

Validate before calling

OLD_PREFIX = 'CELERY_'
def check_settings(settings_dict):
    mixed = [k for k in settings_dict if k.startswith(OLD_PREFIX)]
    if mixed:
        raise SystemExit(f'Remove/rename legacy settings: {mixed}')

Type guard

def is_new_style_key(key: str) -> bool:
    return not key.startswith('CELERY_')

Try / catch

from celery.exceptions import ImproperlyConfigured
try:
    app = Celery('proj', settings_source=...)
except ImproperlyConfigured as e:
    # parse rename suggestions from the message and fix config
    ...

Prevention

When it happens

Trigger: A settings module that defines both `task_default_queue = 'q'` and `CELERY_DEFAULT_QUEUE = 'q2'`; copying config snippets from different Celery version docs; partial migration off the legacy uppercase format.

Common situations: Upgrading from Celery 3.x to 4+ (the big settings rename); mixing project-level new keys with a third-party package that still ships old keys; environment variables injecting old UPPERCASE names alongside new code.

Related errors


AI-assisted analysis of celery/celery@3511be41db (2026-08-09). Data as JSON: /api/errors/a6a33827b2e2d113. Report an issue: GitHub.