Linux & OS Intermediate

Resolving ‘perl: warning: Setting locale failed.’ and Missing POSIX Locale Warnings on Ubuntu 22.04 LTS

Silence persistent locale warnings on Ubuntu 22.04 LTS. Learn to correctly configure system-wide locale settings and eliminate 'perl: warning: Setting locale failed.' messages.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Silence persistent locale warnings on Ubuntu 22.04 LTS. Learn to correctly configure system-wide locale settings and eliminate 'perl: warning: Setting locale failed.' messages.

Introduction

As a Systems Administrator, encountering console output warnings about missing or incorrectly set locale values is a common, albeit annoying, experience on Linux systems. Specifically, on Ubuntu 22.04 LTS, you might frequently see messages like "perl: warning: Setting locale failed." or "locale: Cannot set LC_CTYPE to default locale" when executing various commands, scripts, or logging in via SSH. While these warnings often don't directly halt system operations, they can clutter logs, interfere with script execution, and indicate a misconfiguration that might affect internationalization (i18n) sensitive applications. This guide will meticulously walk you through diagnosing and permanently resolving these locale-related warnings.

Symptom & Error Signature

The most common symptoms involve one or more of the following warning messages appearing in your terminal, especially after logging in, running sudo commands, or executing scripts that use perl or other locale-sensitive utilities:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "UTF-8",
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to a fallback locale (e.g. "en_US.UTF-8").
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

Or, a more generic warning during SSH login or sudo execution:

Warning: locale not set.

And sometimes, subtle issues in cron jobs or automated scripts might manifest as:

(standard_in): is not a tty

While not directly a locale error, this can sometimes be a side effect of a missing or incomplete terminal environment, which includes locale settings, causing utilities to behave unexpectedly in non-interactive contexts.

Root Cause Analysis

The underlying reasons for these locale warnings typically stem from a mismatch or absence of correctly configured and generated locale definitions on the system. Here's a breakdown of the common culprits:

  1. Missing or Incomplete Locale Generation: The system knows which locales are desired (e.g., en_US.UTF-8), but the actual locale data files, which define character sets, collation rules, number formatting, etc., have not been generated or are missing for the specified locale. This is often due to the locales package not being fully configured or locale-gen not being run after modifying /etc/locale.gen.
  2. Incorrect System-Wide Locale Configuration: The /etc/default/locale file, which sets the default system-wide locale variables, might be incorrect, empty, or specify a locale that isn't supported or generated.
  3. User-Specific Overrides: Environment variables set in user-specific configuration files like ~/.bashrc, ~/.profile, or ~/.ssh/environment might override the system-wide settings with invalid or unsupported values, or set LANGUAGE without LANG/LC_ALL.
  4. SSH Server Configuration Issues: When connecting via SSH, the client might try to send its locale settings to the server. If the sshd configuration (/etc/ssh/sshd_config) doesn't permit AcceptEnv LANG LC_*, or if the client's locale is not supported on the server, warnings can occur.
  5. sudo Environment Stripping: By default, sudo is designed to reset most environment variables for security reasons, including locale-related ones. If sudoers configuration doesn't explicitly env_keep the necessary locale variables, commands run with sudo might execute in a bare POSIX C locale, leading to warnings if the executed program expects a different locale.
  6. LC_ALL vs. LANG vs. LANGUAGE:
    • LC_ALL is the "master" locale variable; if set, it overrides all other LC_* variables.
    • LANG sets a default for all LC_* variables that are not explicitly set.
    • LANGUAGE is specific to GNU gettext and defines an ordered list of languages to try. Often, users set LANG but forget LC_ALL, leading to inconsistencies, or set LANGUAGE without LANG or LC_ALL being properly defined.

Step-by-Step Resolution

Follow these steps to systematically diagnose and resolve the locale warnings on your Ubuntu 22.04 LTS system.

1. Verify Current Locale Settings

First, inspect your current locale configuration to understand what the system and your shell environment believe the settings are.

# Check system-wide locale status
locale

# Check environment variables for locale
env | grep LC_
env | grep LANG

You might see output like this, indicating issues:

LANG=en_US.UTF-8
LANGUAGE=
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=

Notice LC_CTYPE="UTF-8" which is an invalid value. It should typically be the same as LANG or LC_ALL (e.g., en_US.UTF-8).

2. Generate and Configure System Locales

This step ensures that your desired locale is actually available and set as the system default.

2.1. Edit /etc/locale.gen

Open the /etc/locale.gen file with a text editor (like nano or vim) and uncomment the lines corresponding to the locales you wish to support. For most Western users, en_US.UTF-8 UTF-8 is sufficient.

sudo nano /etc/locale.gen

Find the line # en_US.UTF-8 UTF-8 and remove the # to uncomment it. If you need other locales (e.g., de_DE.UTF-8), uncomment those as well.

2.2. Generate the Locales

After modifying locale.gen, run locale-gen to generate the locale data files.

sudo locale-gen

You should see output indicating that locales are being generated, for example:

Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.
2.3. Set System-Wide Default Locale

Now, configure the system's default locale settings. We'll set LANG and LC_ALL to ensure consistency. LC_ALL explicitly overrides all other LC_* variables, ensuring a uniform environment.

sudo update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8

This command modifies /etc/default/locale. You can verify its contents:

cat /etc/default/locale

It should look something like this:

LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"

The update-locale command is the preferred method on Ubuntu as it correctly updates /etc/default/locale and performs other necessary actions. Manually editing /etc/default/locale directly is also an option but update-locale is more robust.

3. Address User-Specific Overrides

Sometimes, a user's ~/.bashrc, ~/.profile, or other shell initialization files can override system settings.

3.1. Check User Configuration Files

Inspect your ~/.bashrc and ~/.profile for any lines that set LANG, LC_ALL, LANGUAGE, or other LC_* variables.

grep -E "LANG|LC_|LANGUAGE" ~/.bashrc ~/.profile

If you find conflicting or incorrect settings (e.g., export LC_CTYPE="UTF-8"), you should either:

  • Remove or comment them out: This allows the system-wide settings to take precedence.
  • Correct them: Ensure they match the en_US.UTF-8 (or your chosen locale) format, e.g., export LC_CTYPE="en_US.UTF-8".
3.2. Apply Changes

After modifying user configuration files, apply the changes by sourcing them or logging out and back in:

source ~/.bashrc
source ~/.profile

4. Configure SSH Server (if applicable)

If you primarily encounter these warnings when connecting via SSH, your SSH server configuration might need adjustment.

4.1. Allow Client Locales

Open the sshd_config file:

sudo nano /etc/ssh/sshd_config

Ensure the following line is uncommented:

AcceptEnv LANG LC_*

This tells the SSH server to accept locale environment variables (LANG, LC_ALL, etc.) passed by the client.

4.2. Restart SSH Service

After modifying sshd_config, you must restart the SSH service for changes to take effect.

sudo systemctl restart sshd

Restarting the SSH service will briefly disconnect all active SSH sessions. Ensure you have alternative access or are prepared for a brief interruption.

5. Configure sudo Environment Preservation

If you only see locale warnings when running commands with sudo, it's likely that sudo is stripping the locale environment variables.

5.1. Edit sudoers File

Use visudo to safely edit the sudoers file. This command validates syntax before saving, preventing lockouts.

sudo visudo

Look for the Defaults env_reset line. This line causes sudo to reset the environment. To allow locale variables to pass through, you need to add them to env_keep.

Find the line starting with Defaults env_keep or add one if it doesn't exist (or modify an existing one):

- Defaults        env_reset
+ Defaults        env_reset
+ Defaults        env_keep += "LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION LC_ALL"

Carefully edit the sudoers file using visudo. Incorrect syntax can prevent anyone from using sudo, potentially locking you out of administrative privileges. Always save and exit visudo carefully (e.g., :wq in vi/vim).

6. Test and Verify

After applying the changes, log out of your current session and log back in (or restart your server if you made significant changes to /etc/default/locale).

Then, check the locale settings again:

locale
env | grep LC_
env | grep LANG

All LC_* variables and LANG should now reflect your chosen locale (e.g., en_US.UTF-8), and LC_ALL should also be set.

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.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="en_US.UTF-8"

Finally, try running a command that previously triggered the warning, such as perl or any other script that was verbose about locale issues.

perl -e 'print "Hello from Perl!n"'
sudo locale

If successful, you should no longer see the locale warnings. Your Ubuntu 22.04 LTS system now has properly configured locale settings, ensuring consistent behavior across applications and preventing unnecessary console clutter.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.