python/cpython · info

Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set a

Error message

Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n

What it means

This is the C_LOCALE_COERCION_WARNING printed by _coerce_default_locale_settings (Python/pylifecycle.c) when CPython successfully replaced a legacy C locale with the target UTF-8 locale (e.g. C.UTF-8). It is informational: it tells you the interpreter changed LC_CTYPE behind the scenes and how to opt out. The %.20s is the target locale name, truncated to 20 characters.

Source

Thrown at Python/pylifecycle.c:293

    "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale "
    "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n";

static int
_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)
{
    const char *newloc = target->locale_name;

    /* Reset locale back to currently configured defaults */
    _Py_SetLocaleFromEnv(LC_ALL);

    /* Set the relevant locale environment variable */
    if (setenv("LC_CTYPE", newloc, 1)) {
        fprintf(stderr,
                "Error setting LC_CTYPE, skipping C locale coercion\n");
        return 0;
    }
    if (warn) {
        fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);
    }

    /* Reconfigure with the overridden environment variables */
    _Py_SetLocaleFromEnv(LC_ALL);
    return 1;
}
#endif

int
_Py_CoerceLegacyLocale(int warn)
{
    int coerced = 0;
#ifdef PY_COERCE_C_LOCALE
    char *oldloc = NULL;

    oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));
    if (oldloc == NULL) {
        return coerced;

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Set a real locale in the environment: LANG=C.UTF-8 or LC_CTYPE=<your-locale> so no coercion is needed
  2. Opt out explicitly with PYTHONCOERCECLOCALE=0 if you require the pristine C locale
  3. In Dockerfiles add ENV LANG=C.UTF-8 to silence it permanently

Example fix

# before
ENV LC_ALL=C
# after
ENV LANG=C.UTF-8
Defensive patterns

Strategy: validation

Validate before calling

# silence by making coercion unnecessary
export LC_CTYPE=C.UTF-8   # or LANG=C.UTF-8
python app.py

Prevention

When it happens

Trigger: Starting python with LC_CTYPE=C or LANG=C (or unset, defaulting to C) on a platform that offers C.UTF-8, with PYTHONCOERCECLOCALE unset or not '0', and warnings enabled.

Common situations: Docker/CI images without locale configuration; cron jobs with empty environments; SSH sessions propagating C; users surprised by locale-dependent behavior differences after the implicit switch.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/a378bdf81fa6f8b7. Report an issue: GitHub.