Linux & OS Intermediate

Ubuntu 20.04 LTS: Resolving Missing POSIX Locale Value Warnings

Troubleshoot and fix 'missing POSIX locale' warnings on Ubuntu 20.04 LTS. Learn to configure system, user, and SSH locale settings for a consistent environment.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Troubleshoot and fix 'missing POSIX locale' warnings on Ubuntu 20.04 LTS. Learn to configure system, user, and SSH locale settings for a consistent environment.

Introduction

As a seasoned Systems Administrator, encountering unexpected warnings in console output or application logs can be a source of frustration. One common issue on Linux systems, particularly Ubuntu 20.04 LTS, is the "missing POSIX locale value" warning. This often manifests as messages about LC_ALL, LANG, or LANGUAGE being unset or incorrectly configured, leading to applications falling back to default locales or displaying garbled characters in specific scenarios. While often benign, these warnings can prevent certain programs from behaving as expected, impact scripts, and clutter logs, signaling an underlying misconfiguration of your system's internationalization settings. This guide will walk you through the precise steps to diagnose and resolve this issue, ensuring a consistent and correctly configured locale environment on your Ubuntu 20.04 server.

Symptom & Error Signature

Users typically encounter these warnings when logging in via SSH, running specific command-line tools (like perl, man, apt), executing cron jobs, or starting services. The exact output can vary but generally points to locale-related issues.

Common error messages include:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "UTF-8",
        LC_MESSAGES = "en_US.UTF-8"
    are correct and installed on your system.
perl: warning: Falling back to a fallback locale ("en_US.UTF-8").

Or a more generic shell warning:

-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

Sometimes, when connecting via SSH, you might see:

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

Applications relying on gettext or other internationalization libraries might also print similar warnings, indicating a fallback from the user's preferred locale to a system default, often C or POSIX.

Root Cause Analysis

The "missing POSIX locale value" warning fundamentally stems from a mismatch or absence of locale definitions on the system. Here's a breakdown of the common root causes:

  1. Locale Not Generated: The most frequent cause is that the desired locale (e.g., en_US.UTF-8) is not actually generated or installed on the system. While the system might know about a locale, it cannot use it unless it's explicitly generated.
  2. Incorrect Environment Variables:
    • LANG and LC_ALL: These crucial environment variables define the system's preferred locale. If they are unset, set to an invalid value, or point to a non-existent locale, applications will complain. LC_ALL overrides all other LC_* variables and LANG.
    • LANGUAGE: While often left unset or set to en_US:en, it's primarily used for specifying an ordered list of desired languages for gettext messages. Misconfiguration can contribute to warnings.
  3. SSH Client/Server Mismatch:
    • Client Sending Invalid Locales: Your SSH client (e.g., PuTTY, OpenSSH client) might be configured to send locale environment variables to the server, but those values are not generated or valid on the server.
    • SSH Server Not Accepting Locales: The SSH daemon (sshd) on the server might be configured to explicitly not accept LANG or LC_* environment variables from the client.
  4. Application-Specific Locale Settings: Certain applications (e.g., perl, python) or scripts might explicitly try to set a locale that is either unavailable or conflicts with system settings, leading to warnings.
  5. systemd Service Environment: Background services or cron jobs managed by systemd often run in a minimal environment. If their Environment or the global DefaultEnvironment in systemd is not configured with appropriate locale variables, warnings can appear in service logs.

Step-by-Step Resolution

Follow these steps to diagnose and correct your system's locale configuration.

1. Check Current System Locales and Generated Locales

First, verify what locales are currently set and which ones are available on your system.

locale
locale -a
  • locale will show the currently active locale settings for your session. Look for any (unset) values or unexpected outputs.
  • locale -a lists all generated locales on your system. If your desired locale (e.g., en_US.UTF-8) is not in this list, it needs to be generated.

2. Generate Missing Locales

If locale -a does not list your desired locale, you need to enable it for generation.

Modifying /etc/locale.gen and running locale-gen is crucial for making locales available system-wide. Incorrectly generated locales can lead to character display issues or application errors.

  1. Edit the locale.gen file: Open /etc/locale.gen with a text editor (e.g., nano or vim):

    sudo nano /etc/locale.gen
    
  2. Uncomment your desired locale: Find the line corresponding to your desired locale (e.g., en_US.UTF-8 UTF-8) and uncomment it by removing the # character at the beginning of the line. For a standard English UTF-8 locale, ensure this line is uncommented:

    # en_AG.UTF-8 UTF-8
    # en_AU.UTF-8 UTF-8
    en_US.UTF-8 UTF-8
    # en_CA.UTF-8 UTF-8
    

    Save and exit the file (Ctrl+O, Enter, Ctrl+X for nano).

  3. Generate the locales: Run the locale-gen command to generate the uncommented locales:

    sudo locale-gen
    

    You should see output indicating the generation process, for example:

    Generating locales (this might take a while)...
      en_US.UTF-8... done
    Generation complete.
    

    After this, locale -a should include en_US.utf8.

3. Set System-Wide Default Locales

After generating the locales, you need to inform the system which one to use by default.

  1. Use update-locale command: This is the recommended way to set system-wide locales on Debian/Ubuntu systems as it correctly updates /etc/default/locale.

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

    LANG sets the default locale, while LC_ALL explicitly overrides all other LC_* categories (e.g., LC_CTYPE, LC_MESSAGES). Setting both to en_US.UTF-8 provides the most consistent environment.

  2. Verify the change: You can inspect the /etc/default/locale file:

    cat /etc/default/locale
    

    It should now contain:

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

    For these changes to take full effect system-wide, a reboot is often recommended, especially for services. However, for your current shell session, you can log out and log back in, or simply run source /etc/default/locale (though this only affects the current shell, not new processes).

4. Configure User-Specific Locales (If Necessary)

Sometimes, specific users might need different locale settings or have overrides in their shell profiles. Check your ~/.bashrc, ~/.profile, or ~/.ssh/environment files.

  1. Inspect user shell configuration files:

    cat ~/.bashrc
    cat ~/.profile
    

    Look for lines similar to:

    export LANG="C.UTF-8" # Or any other locale
    export LC_ALL=""
    

    If these lines are present and conflict with your desired system-wide settings, either remove them or adjust them to match:

    # export LANG="en_US.UTF-8" # Uncomment or add if needed, prefer system-wide
    # export LC_ALL="en_US.UTF-8"
    

    Be cautious when modifying user shell profiles. Incorrect changes can affect your terminal behavior. Always make a backup before editing (cp ~/.bashrc ~/.bashrc.bak).

  2. Apply changes: After editing, apply the changes to your current session:

    source ~/.bashrc
    # or
    source ~/.profile
    

    Then re-check locale.

5. Address SSH Server Configuration

If the warnings appear specifically when you SSH into the server, the SSH server's configuration might be a factor.

  1. Check sshd_config: Open the SSH daemon configuration file:

    sudo nano /etc/ssh/sshd_config
    

    Ensure that the following lines are uncommented and present:

    # Accept client-supplied environment variables
    AcceptEnv LANG LC_*
    

    If you modified it, restart the SSH service:

    sudo systemctl restart sshd
    

    Modifying sshd_config requires a restart of the sshd service, which will temporarily disconnect all SSH sessions. Ensure you have alternative access (e.g., console or a second SSH session) before restarting.

  2. Check SSH Client Configuration: On your local machine (client), check your SSH client configuration (~/.ssh/config or /etc/ssh/ssh_config). Ensure you are not sending incorrect locale variables. If you have SendEnv configured, verify the sent variables are valid on the server. For example, if you have:

    Host your_server
        SendEnv LANG LC_*
    

    This tells your client to send your local LANG and LC_* variables. If your local machine uses en_GB.UTF-8 and the server only has en_US.UTF-8 generated, you might get warnings. You can either ensure the server supports your client's locale or comment out SendEnv if it's causing issues.

6. Configure Locales for systemd Services and Cron Jobs

Background processes and systemd services often run without a full interactive shell environment, meaning they don't inherit locale settings from .bashrc or .profile.

  1. For Specific systemd Services: If a particular service is emitting locale warnings, you can define locale variables directly in its systemd service unit file (.service).

    sudo systemctl edit your-service.service
    

    Add an Environment directive in the [Service] section:

    [Service]
    Environment="LANG=en_US.UTF-8" "LC_ALL=en_US.UTF-8"
    

    Save, then reload systemd and restart the service:

    sudo systemctl daemon-reload
    sudo systemctl restart your-service.service
    
  2. For Global systemd Environment (for User Services/Cron): You can set default environment variables for all systemd user services and cron jobs that run under a user session. Create a drop-in configuration file for systemd:

    sudo mkdir -p /etc/systemd/system.conf.d/
    sudo nano /etc/systemd/system.conf.d/locale.conf
    

    Add the desired environment variables:

    [Manager]
    DefaultEnvironment="LANG=en_US.UTF-8" "LC_ALL=en_US.UTF-8"
    

    For user-level services/timers (e.g., those managed by crontab -e and systemd user timers), you might also need to configure /etc/systemd/user.conf.d/locale.conf similarly. Apply the changes and reboot or log out/in:

    sudo systemctl daemon-reload
    # Reboot for system-wide effect, or just log out and back in for user sessions.
    

7. Final Verification

After implementing the changes, log out of your session and log back in. Run the locale command again and check if the warnings have disappeared. Execute any scripts or commands that previously triggered the warnings.

locale

The output should now look clean, with LANG and LC_ALL correctly 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

By following these comprehensive steps, you should successfully eliminate the "missing POSIX locale value" warnings and ensure a robust and consistent internationalization environment on your Ubuntu 20.04 LTS server.

👨‍💻

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.