Quick Tip: Fixing Locale Warnings/Notices Issues on Linux Server (or Desktop)

Some locale issues (errors, warnings or notices) might bug you on a linux box (in my case Ubuntu) when executing various commands:

$ schroot
terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
Aborted

$ man schroot
man: can't set the locale; make sure $LC_* and $LANG are correct

$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory

$ perl -v
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = "en_US:en",
	LC_ALL = (unset),
	LC_CTYPE = "UTF-8",
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi
(with 56 registered patches, see perl -V for more detail)

Copyright 1987-2011, Larry Wall

To fix or suppress these, first check out what’s the locale being used currently and also those that are installed, using these commands:

[bash]
$ locale # Current locale settings
locale: Cannot set LC_CTYPE 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
LANGUAGE=en_US:en
LC_CTYPE=UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

$ locale -a # locales available on your system
C
C.UTF-8
en_AG
en_AG.utf8
en_AU.utf8
en_BW.utf8
en_CA.utf8
en_DK.utf8
en_GB.utf8
en_HK.utf8
en_IE.utf8
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ.utf8
en_PH.utf8
en_SG.utf8
en_US.utf8
en_ZA.utf8
en_ZM
en_ZM.utf8
en_ZW.utf8
POSIX
[/bash]

As you can see above, LC_ALL= is empty, which was the problem in my case. There are several ways to set it to the proper locale string value from the list above. First one is using the update-locale program/command.

[bash]
$ sudo update-locale LC_ALL="en_US.UTF-8"
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = "en_US:en",
LC_ALL = (unset),
LC_CTYPE = "UTF-8",
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
[/bash]

This command just adds LC_ALL=en_US.UTF-8 to /etc/default/locale, which means you can also do this manually instead of executing the command, whichever way you prefer. In older ubuntu releases the LC_ALL environment variable had to be added to /etc/environment.

[bash]
$ cat /etc/default/locale
# File generated by update-locale
LANGUAGE=en_US:en
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8

$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
[/bash]

Note: With this method, a fresh login is required for the change to take effect.

The other way to fix this locale issue (which is what I did) is to export this same variable in ~/.bash_profile and source it. So add export LC_ALL="en_US.UTF-8" to .bash_profile using your favourite text editor first, then source it.

[bash]
$ vim ~/.bash_profile # add `export LC_ALL="en_US.UTF-8"`
$ . ~/.bash_profile # source it
$ perl -v # no more warnings/notices

This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi
(with 56 registered patches, see perl -V for more detail)

Copyright 1987-2011, Larry Wall
[/bash]

Execute $ locale now, all your variables (settings) should be set to some value, but just incase LANG and LANG_CTYPE are still empty, then repeat the same process above for these 2 variables too!

After all these steps, if you’re still out of luck, then try regenerating the locales using this command:

[bash]
$ sudo locale-gen
Generating locales…
en_AG.UTF-8… up-to-date
en_AU.UTF-8… up-to-date
en_BW.UTF-8… up-to-date
en_CA.UTF-8… up-to-date
en_DK.UTF-8… up-to-date
en_GB.UTF-8… up-to-date
en_HK.UTF-8… up-to-date
en_IE.UTF-8… up-to-date
en_IN.UTF-8… up-to-date
en_NG.UTF-8… up-to-date
en_NZ.UTF-8… up-to-date
en_PH.UTF-8… up-to-date
en_SG.UTF-8… up-to-date
en_US.UTF-8… up-to-date
en_ZA.UTF-8… up-to-date
en_ZM.UTF-8… up-to-date
en_ZW.UTF-8… up-to-date
Generation complete.
[/bash]

Also check the ones being used in the $ locale output, you may have something like fr_FR.UTF-8 set and may need to generate it too:

[bash]
$ sudo locale-gen fr_FR.UTF-8
Generating locales…
fr_FR.UTF-8… done
Generation complete.
[/bash]

This will also append fr_FR.UTF-8 to /var/lib/locales/supported.d/local for future regenerations ($ sudo locale-gen).

[bash]
$ cat /var/lib/locales/supported.d/local
en_US.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8
[/bash]

Hope that helps!

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.