Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 8 min read Last reviewed Jul 2026

Linux Error Guide: 'setlocale: LC_ALL: cannot change locale' — Fix Missing Locales

Quick answer

Fix Linux 'setlocale: cannot change locale' warnings: generate the missing locale, set LANG and LC_ALL, and stop SSH forwarding unset locales.

  • #linux
  • #troubleshooting
  • #errors
  • #locale
Free toolkit

Stuck on this Linux Admins error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

This warning floods your terminal whenever a program initializes its locale and the requested locale is not installed on the system. It is most common after a fresh minimal install or over SSH:

-bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8): No such file or directory

Perl is the loudest offender and prints its own multi-line variant during apt/dpkg runs:

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").

The message is only a warning — the program falls back to the C/POSIX locale — but it signals that character handling, sorting, and date formatting are not what you expect, and it clutters automation logs.

Symptoms

  • Every login shell, sudo, or apt/dpkg invocation prints a setlocale warning.
  • perl: warning: Setting locale failed appears during package installs.
  • UTF-8 filenames render as ???? or mojibake; sort orders bytes instead of letters.
  • The warnings appear only when you SSH in, but not on the local console.
  • locale output shows the requested value but the program still falls back to C.

Common Root Causes

  • The locale is not generated. The variable names a locale (e.g., en_US.UTF-8) that was never built into /usr/lib/locale/locale-archive.
  • locales package not installed / minimal image. Container base images and cloud minimal installs ship almost no locales.
  • SSH forwards a client locale the server lacks. SendEnv LANG LC_* on the client plus AcceptEnv on the server pushes your laptop’s locale onto a server that never generated it.
  • Locale set but archive not regenerated. /etc/default/locale or /etc/locale.conf names a locale that locale-gen was never re-run for.
  • Typo or wrong charmap. en_US.utf8 vs en_US.UTF-8, or a locale with no matching charmap entry in /etc/locale.gen.

Diagnostic Workflow

Confirm what is requested versus what exists. locale prints the active settings and complains about each unset/invalid one:

locale
locale 2>&1 | grep -i 'cannot change'

List the locales that are actually generated on this host:

locale -a
locale -a | grep -i en_US

Check the configured defaults (Debian/Ubuntu vs RHEL paths differ):

cat /etc/default/locale        # Debian / Ubuntu
cat /etc/locale.conf           # RHEL / Fedora / systemd
grep -v '^#' /etc/locale.gen | grep -v '^$'   # what is enabled to build

If it only happens over SSH, prove the client is pushing the locale:

ssh user@host 'locale'                 # shows forwarded values
grep -i sendenv /etc/ssh/ssh_config ~/.ssh/config
sudo grep -i acceptenv /etc/ssh/sshd_config

Example Root Cause Analysis

A team reported setlocale warnings on every apt install on a new Ubuntu cloud image, but only when connecting from macOS laptops.

Running locale -a on the server showed just C, C.UTF-8, and POSIXen_US.UTF-8 was never generated. Meanwhile ssh host 'locale' returned LC_ALL=en_US.UTF-8, proving the Mac’s Terminal was forwarding LC_ALL via SendEnv LANG LC_*, and the server’s AcceptEnv LANG LC_* was accepting a locale it did not have.

Two fixes applied together resolved it: generating the locale on the server so the forwarded value became valid, and removing the blind SendEnv on the clients so unset locales stopped propagating. After locale-gen en_US.UTF-8 and update-locale LANG=en_US.UTF-8, locale -a listed en_US.utf8 and the warnings stopped for all users.

Prevention Best Practices

  • Bake a locale into base images: install locales (Debian) or glibc-langpack-en (RHEL) and generate en_US.UTF-8 (or C.UTF-8) during image build, not at first login.
  • Prefer C.UTF-8 for servers and containers — it is always available, UTF-8 clean, and needs no generation.
  • On SSH clients, avoid a blanket SendEnv LC_*; forward only what remote hosts are guaranteed to support, or nothing.
  • Set the default explicitly with update-locale/localectl and re-run locale-gen whenever you change /etc/locale.gen.
  • Add a locale -a check to image-build CI so a missing locale fails the build instead of every runtime login.

Quick Command Reference

# Debian / Ubuntu: enable, generate, and set a locale
sudo apt-get install -y locales
sudo sed -i 's/# en_US.UTF-8/en_US.UTF-8/' /etc/locale.gen
sudo locale-gen
sudo update-locale LANG=en_US.UTF-8

# RHEL / Fedora
sudo dnf install -y glibc-langpack-en
sudo localectl set-locale LANG=en_US.UTF-8

# Safe universal default (no generation needed)
sudo update-locale LANG=C.UTF-8

# Verify
locale -a | grep -i utf
locale

Conclusion

setlocale: cannot change locale is a mismatch between the locale a program asks for and the locales actually built on the host — very often amplified by SSH forwarding a client’s locale to a bare server. Generate the locale you want (or standardize on C.UTF-8), set it explicitly with update-locale/localectl, and stop clients from pushing locales servers don’t have. Bake this into your images and the warnings disappear for good.

Free download · 368-page PDF

Fixed it? Get 500 Linux Admins & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.