{"record":{"id":"a378bdf81fa6f8b7","repo":"python/cpython","slug":"python-detected-lc-ctype-c-lc-ctype-coerced-to","errorCode":null,"errorMessage":"Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\\n","messagePattern":"Python detected LC_CTYPE=C: LC_CTYPE coerced to %\\.20s \\(set another locale or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior\\)\\.\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"Python/pylifecycle.c","lineNumber":293,"sourceCode":"    \"Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale \"\n    \"or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\\n\";\n\nstatic int\n_coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target)\n{\n    const char *newloc = target->locale_name;\n\n    /* Reset locale back to currently configured defaults */\n    _Py_SetLocaleFromEnv(LC_ALL);\n\n    /* Set the relevant locale environment variable */\n    if (setenv(\"LC_CTYPE\", newloc, 1)) {\n        fprintf(stderr,\n                \"Error setting LC_CTYPE, skipping C locale coercion\\n\");\n        return 0;\n    }\n    if (warn) {\n        fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc);\n    }\n\n    /* Reconfigure with the overridden environment variables */\n    _Py_SetLocaleFromEnv(LC_ALL);\n    return 1;\n}\n#endif\n\nint\n_Py_CoerceLegacyLocale(int warn)\n{\n    int coerced = 0;\n#ifdef PY_COERCE_C_LOCALE\n    char *oldloc = NULL;\n\n    oldloc = _PyMem_RawStrdup(setlocale(LC_CTYPE, NULL));\n    if (oldloc == NULL) {\n        return coerced;","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Python/pylifecycle.c#L275-L311","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set a real locale in the environment: LANG=C.UTF-8 or LC_CTYPE=<your-locale> so no coercion is needed","Opt out explicitly with PYTHONCOERCECLOCALE=0 if you require the pristine C locale","In Dockerfiles add ENV LANG=C.UTF-8 to silence it permanently"],"exampleFix":"# before\nENV LC_ALL=C\n# after\nENV LANG=C.UTF-8","handlingStrategy":"validation","validationCode":"# silence by making coercion unnecessary\nexport LC_CTYPE=C.UTF-8   # or LANG=C.UTF-8\npython app.py","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure a UTF-8 locale in Dockerfiles (ENV LANG=C.UTF-8) and CI matrices","Use PYTHONCOERCECLOCALE=0 to opt out when C-locale semantics are required","Don't rely on the warning being absent as a health check — assert locale explicitly in tests"],"tags":["locale","cpython","startup","environment","utf-8"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}