Enable UTF-8 Locale on Linux

Deepak Prasad
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:

bash
locale

On RHEL, Rocky Linux, AlmaLinux, or Fedora, set a UTF-8 system default:

bash
sudo localectl set-locale LANG=en_US.UTF-8

On Debian or Ubuntu, generate the locale and set the default:

bash
sudo locale-gen en_US.UTF-8

Set the system default with update-locale:

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

Confirm UTF-8 is active in a new login session:

bash
locale charmap

Sample output:

output
UTF-8

Open 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:

bash
locale

Sample output on vm1.lab.example:

output
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:

bash
localectl status

Sample output:

output
System Locale: LANG=en_US.UTF-8
    VC Keymap: us
   X11 Layout: us
    X11 Model: pc105

The file that survives reboot on RHEL-family systems is /etc/locale.conf:

bash
grep LANG /etc/locale.conf

Sample output:

output
LANG="en_US.UTF-8"

Enable UTF-8 on RHEL Rocky AlmaLinux and Fedora

List UTF-8 locales already available on the system:

bash
localectl list-locales | grep '\.UTF-8$' | tail -8

Sample output (truncated from the end of the list):

output
zh_CN.UTF-8
zh_HK.UTF-8
zh_SG.UTF-8
zh_TW.UTF-8
zu_ZA.UTF-8

Pick 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:

bash
sudo localectl set-locale LANG=en_US.UTF-8

The command updates /etc/locale.conf immediately:

bash
grep LANG /etc/locale.conf

Sample output:

output
LANG=en_US.UTF-8

You can edit the same file by hand if you prefer:

text
LANG=en_US.UTF-8

Save 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:

bash
sudo dnf install glibc-langpack-en

Adjust 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:

bash
locale -a | grep -i utf

If en_US.UTF-8 is missing from that list, generate it:

bash
sudo locale-gen en_US.UTF-8

Apply the system default:

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

Reconnect 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:

bash
export LANG=en_US.UTF-8

To override every category at once during troubleshooting:

bash
export LC_ALL=en_US.UTF-8

These 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:

bash
locale

Then check the active character map:

bash
locale charmap

Sample output:

output
UTF-8

When 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


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.


Frequently Asked Questions

1. What is the difference between LANG and LC_ALL?

LANG sets the default locale for all categories unless another LC_* variable overrides it. LC_ALL overrides every category at once and is useful for temporary testing in a single shell.

2. Do I need to reboot after enabling UTF-8?

No. After changing the system locale, open a new login session or reconnect over SSH. Existing shells keep the old LANG until you log out or export the new value manually.

3. Is en_US.UTF-8 the same as en_US.utf8?

On most Linux systems they refer to the same UTF-8 locale. locale -a may list en_US.utf8 while localectl and /etc/locale.conf use en_US.UTF-8.

4. Why do I see a Perl warning about falling back to a locale?

The shell or script is running with a locale that is not generated or not installed. Set LANG to an available UTF-8 locale and install the matching language pack or run locale-gen on Debian-family systems.

5. How do I check whether UTF-8 is already enabled?

Run locale and confirm LANG ends in .UTF-8, then run locale charmap and look for UTF-8 output.
Omer Cakmak

Linux Administrator

Highly skilled at managing Debian, Ubuntu, CentOS, Oracle Linux, and Red Hat servers. Proficient in bash scripting, Ansible, and AWX central server management, he handles server operations on OpenStack, KVM, Proxmox, and VMware.

  • Debian
  • Ubuntu
  • Linux
  • Red Hat Enterprise Linux
  • Shell Script
  • System Administration