locale: Cannot set LC_ALL to default locale: No such file or directory means
LANG or LC_ALL names a locale, here en_US.UTF-8,
that was never generated on this system. Install the locales package and run
locale-gen en_US.UTF-8, or set the variables to C.UTF-8, which
is already there.
The same missing locale makes perl print perl: warning: Setting locale
failed. and bash print setlocale warnings; one fix silences all of
them.
The error
docker exec fix10-lc-r4 bash -c 'echo LANG=$LANG LC_ALL=$LC_ALL; locale 2>&1'
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=en_US.UTF-8
...
Any perl program, even a one-liner, adds its own warning and falls back to "C":
docker exec fix10-lc-r4 bash -c 'perl -e ''print qq(perl ok\n)'' 2>&1'
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = "en_US.UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
perl ok
Why it happens
The container was started with -e LANG=en_US.UTF-8 -e LC_ALL=en_US.UTF-8,
a common US English setting. The ubuntu:24.04 image
has only three locales, and en_US.utf8 is not one of them:
docker exec fix10-lc-r4 bash -c 'locale -a 2>&1'
...
C
C.utf8
POSIX
bash, locale and perl each reported that the locale named in the variables
could not be set.
These are warnings: the perl one-liner still printed perl ok. But perl said it fell back to the plain "C" locale,
and the warnings came back with every command run in that container.
The fix
Generate the locale the variables name:
docker exec fix10-lc-r4 bash -c 'apt-get update > /dev/null 2>&1; apt-get install -y locales > /dev/null 2>&1; echo install-exit=$?'
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
install-exit=0
docker exec fix10-lc-r4 bash -c 'locale-gen en_US.UTF-8 2>&1'
...
Generating locales (this might take a while)...
en_US.UTF-8... done
Generation complete.
docker exec fix10-lc-r4 bash -c 'locale -a 2>&1; perl -e ''print qq(perl ok\n)'' 2>&1; locale 2>&1 | head -3'
C
C.utf8
en_US.utf8
POSIX
perl ok
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
Do not be put off by the spelling in the list: locale -a shows the new
locale as en_US.utf8, while the variables still say
en_US.UTF-8, and the two matched in the test. The warnings stopped in the
same container without restarting it, because the variables had been right all along;
only the locale files were missing.
Or, when you do not need US English formats, point the variables at the locale the
image already has. A container started with C.UTF-8 printed no warning:
docker run -d --name fix10-lc-r5 -e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 ubuntu:24.04 sleep infinity
docker exec fix10-lc-r5 bash -c 'locale 2>&1 | head -3; perl -e ''print qq(perl ok\n)'' 2>&1'
LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
perl ok
Setting LC_ALL=C.UTF-8 only for one command inside the broken container
quietened perl but not the outer shell, which had already read the old value; change the
variables where they are set (in this test, the docker run line), not per
command.
How it was reproduced
The capture was made in ubuntu:24.04 containers (Ubuntu 24.04.5 LTS, bash
5.2.21) on Docker Engine 29.9.3, the broken one started with
docker run -d --name fix10-lc-r4 -e LANG=en_US.UTF-8 -e LC_ALL=en_US.UTF-8 ubuntu:24.04 sleep infinity; it was not run in WSL. The installed package was
locales 2.39-0ubuntu8.12. The fix10-lc- container names are the
test's own.
Every command was sent from Windows PowerShell 5.1 exactly as shown, with the -c text in single quotes so it reached the container unchanged; a single quote inside that text is written twice, as PowerShell requires.
Frequently asked
- How do I fix perl: warning: Setting locale failed in Ubuntu?
- Generate the locale your LANG and LC_ALL name: apt-get install -y locales, then locale-gen en_US.UTF-8. In the test perl then ran without warnings.
- Why does locale say Cannot set LC_ALL to default locale?
- LC_ALL names a locale that is not generated. In the test locale -a listed only C, C.utf8 and POSIX while LC_ALL was en_US.UTF-8.
- Can I use C.UTF-8 instead of en_US.UTF-8?
- Yes, ubuntu:24.04 already has it. A container started with LANG and LC_ALL set to C.UTF-8 printed no locale warning in the test.
More decoded errors in the Fixes category.