| Tested on | RHEL 10.2 (Coughlan) — vm1.lab.example |
|---|---|
| Package | glibc 2.39-128.el10_2 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Fedora, Ubuntu, Debian, and other Linux distributions using glibc locales |
| Privilege | Normal user to check settings; sudo or root to change system locale files and run localectl / update-locale |
| Scope | Check locale variables, set a UTF-8 system default on RHEL-family and Debian-family hosts, apply UTF-8 in the current shell, and verify encoding. Does not cover desktop input methods or converting existing files between encodings. |
| Related guides | sudo command dpkg command Where to set environment variables in Linux Set timezone on Ubuntu |
UTF-8 is the standard choice for modern Linux locales because it supports Unicode text across shells, applications, and logs. If LANG points to a locale that is missing or incorrectly configured, applications may show locale warnings or unexpected character handling.
The commands below were run on vm1.lab.example. Replace en_US.UTF-8 with the language and region you need, as long as the name ends in .UTF-8.
Quick answer
Check the active locale:
localeOn RHEL, Rocky Linux, AlmaLinux, or Fedora, set a UTF-8 system default:
sudo localectl set-locale LANG=en_US.UTF-8On Debian or Ubuntu, generate the locale and set the default:
sudo locale-gen en_US.UTF-8Set the system default with update-locale:
sudo update-locale LANG=en_US.UTF-8Confirm UTF-8 is active in a new login session:
locale charmapSample output:
UTF-8Open a new SSH session after system-wide changes. Existing shells keep the old LANG until you reconnect or export the new value.
Check current locale settings
Start with the locale variables your shell is using right now:
localeSample output on vm1.lab.example:
LANG=en_US.UTF-8
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=When UTF-8 is configured, LANG and the LC_* lines end in .UTF-8. An empty LC_ALL means individual categories follow LANG.
On systemd-based RPM hosts, localectl shows the persistent system setting:
localectl statusSample output:
System Locale: LANG=en_US.UTF-8
VC Keymap: us
X11 Layout: us
X11 Model: pc105The file that survives reboot on RHEL-family systems is /etc/locale.conf:
grep LANG /etc/locale.confSample output:
LANG="en_US.UTF-8"Enable UTF-8 on RHEL Rocky AlmaLinux and Fedora
List UTF-8 locales already available on the system:
localectl list-locales | grep '\.UTF-8$' | tail -8Sample output (truncated from the end of the list):
zh_CN.UTF-8
zh_HK.UTF-8
zh_SG.UTF-8
zh_TW.UTF-8
zu_ZA.UTF-8Pick a locale from that list — en_US.UTF-8 and en_GB.UTF-8 are common defaults on English systems.
Set the system default with localectl:
sudo localectl set-locale LANG=en_US.UTF-8The command updates /etc/locale.conf immediately:
grep LANG /etc/locale.confSample output:
LANG=en_US.UTF-8You can edit the same file by hand if you prefer:
LANG=en_US.UTF-8Save the file, then confirm localectl status shows the new value.
Log out and open a new SSH session (or reboot) before you trust locale in an old shell — the session you used to run localectl may still show the previous LANG.
If localectl set-locale fails or locale -a does not list your target locale, install language packs. On RHEL 8 and later, packages such as glibc-langpack-en or glibc-all-langpacks provide additional locales:
sudo dnf install glibc-langpack-enAdjust the package name for your language (glibc-langpack-de, and so on).
Enable UTF-8 on Debian and Ubuntu
On Debian and Ubuntu, use update-locale to set the system default rather than editing the locale file directly. Depending on the distribution and release, the resulting configuration may be stored in /etc/default/locale or /etc/locale.conf. Locale data is generated from entries in /etc/locale.gen.
Check what is already generated:
locale -a | grep -i utfIf en_US.UTF-8 is missing from that list, generate it:
sudo locale-gen en_US.UTF-8Apply the system default:
sudo update-locale LANG=en_US.UTF-8Reconnect over SSH or start a new login session so PAM picks up the change. On Debian, dpkg-reconfigure locales offers an interactive picker for the same settings if you prefer a menu over the commands above — the dpkg command docs describe how package configuration hooks work.
Set UTF-8 for the current shell session only
System-wide changes do not alter an already-open terminal. For a one-off test in the current shell, export LANG:
export LANG=en_US.UTF-8To override every category at once during troubleshooting:
export LC_ALL=en_US.UTF-8These exports last until you close the shell. They do not replace the persistent system locale set by localectl or update-locale. For lasting defaults, use those tools as shown above.
Verify UTF-8 is active
After a new login session, confirm LANG ends in .UTF-8:
localeThen check the active character map:
locale charmapSample output:
UTF-8When locale charmap prints UTF-8, the locale configuration is using a UTF-8 character set. Tools may list the same locale as en_US.utf8 in locale -a while localectl and /etc/locale.conf use en_US.UTF-8 — the spelling differs, not the encoding.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
locale: Cannot set LC_* to default locale |
Locale not generated or langpack missing | On RHEL: dnf install glibc-langpack-en; on Debian/Ubuntu: locale-gen en_US.UTF-8 |
localectl set-locale succeeded but locale unchanged |
Old shell session | Log out and SSH in again, or export LANG=en_US.UTF-8 in the current shell |
Perl warning: Setting locale failed |
Script locale not available | Set LANG to a generated UTF-8 locale; avoid empty or C locale in cron jobs |
| Garbled characters in the terminal (é instead of é) | Terminal or SSH client encoding, or the file's actual encoding — not always LANG |
Confirm locale charmap prints UTF-8; set the terminal emulator and SSH client to UTF-8 |
Desired locale missing from localectl list-locales |
Language pack not installed | Install the matching glibc-langpack-* package, then retry |
References
- locale(7) — Linux manual page
- systemd localectl man page
- Debian Wiki — Locale
- Red Hat — Configuring language settings
Summary
UTF-8 on Linux is configured through locale variables, not a separate toggle. Check locale and localectl status first, then set a .UTF-8 locale name such as en_US.UTF-8 with localectl set-locale on RHEL-family systems or locale-gen plus update-locale on Debian and Ubuntu.
System-wide changes take effect for new login sessions; existing shells keep the old values until you reconnect. Confirm the result with locale and locale charmap in a fresh session — locale charmap should print UTF-8.
If a locale name is missing entirely, install the matching glibc langpack on RPM systems or regenerate locales on Debian before you set LANG. That clears most “cannot set locale” and Perl fallback warnings without changing application code.

