What's Actually Happening
Linux system locale is not configured properly. Applications cannot display text correctly, dates and numbers appear in wrong formats, or system displays locale warnings.
The Error You'll See
Locale warning:
```bash $ ls
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LANG = "en_US.UTF-8" are supported and installed on your system. ```
Locale missing:
```bash $ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to default locale: No such file or directory locale: Cannot set LC_ALL to default locale: No such file or directory ```
Command error:
```bash $ man ls
man: can't set the locale; make sure $LC_* and $LANG are appropriate
```
Package installation:
```bash $ apt install package
dpkg: warning: 'not a tty' not found; using 'tty' instead perl: warning: Setting locale failed. ```
Why This Happens
- 1.Locale not installed - Language pack missing from system
- 2.Environment unset - LANG/LC_ALL environment variables not configured
- 3.Configuration missing - Locale not in /etc/locale.conf or /etc/default/locale
- 4.SSH locale forwarding - Remote system doesn't have locale
- 5.Broken locale package - Locale package corrupted or incomplete
- 6.Docker container - Minimal containers without locale support
Step 1: Check Current Locale Settings
```bash # Check locale: locale
# Output: # LANG=en_US.UTF-8 # LC_CTYPE="en_US.UTF-8" # LC_NUMERIC="en_US.UTF-8" # ...
# Check available locales: locale -a
# Output should include: # en_US.utf8 # C # C.UTF-8
# Check locale environment: echo $LANG echo $LC_ALL echo $LANGUAGE
# Check locale config file: cat /etc/locale.conf # CentOS/RHEL cat /etc/default/locale # Debian/Ubuntu
# Check for missing: locale -a | grep -i en_US ```
Step 2: Install Missing Locale Packages
```bash # Debian/Ubuntu: apt update apt install locales -y
# Generate locales: dpkg-reconfigure locales
# Or manually: locale-gen en_US.UTF-8
# Update locale: update-locale LANG=en_US.UTF-8
# CentOS/RHEL 7/8: yum install langpacks-en glibc-langpack-en -y
# Or: dnf install langpacks-en glibc-langpack-en -y
# Fedora: dnf install langpacks-en -y
# Arch Linux: pacman -S glibc # Locales generated during install
# Alpine Linux: apk add --no-cache musl-locales ```
Step 3: Generate Specific Locales
```bash # Debian/Ubuntu - edit locales file: vim /etc/locale.gen
# Uncomment needed locales: en_US.UTF-8 UTF-8 en_GB.UTF-8 UTF-8 zh_CN.UTF-8 UTF-8
# Generate: locale-gen
# Output: # Generating locales... # en_US.UTF-8... done # en_GB.UTF-8... done
# Generate specific locale: locale-gen en_US.UTF-8
# Check available: locale -a
# For Chinese locale: locale-gen zh_CN.UTF-8 update-locale LANG=zh_CN.UTF-8
# For German: locale-gen de_DE.UTF-8 ```
Step 4: Set System Default Locale
```bash # Debian/Ubuntu: update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
# Check file: cat /etc/default/locale
# Output: # LANG=en_US.UTF-8 # LC_ALL=en_US.UTF-8
# CentOS/RHEL: localectl set-locale LANG=en_US.UTF-8
# Check: localectl status
# Edit config file: vim /etc/locale.conf LANG=en_US.UTF-8
# Fedora: localectl set-locale LANG=en_US.UTF-8
# Arch Linux: vim /etc/locale.conf LANG=en_US.UTF-8
# Apply without restart: source /etc/default/locale # Debian/Ubuntu . /etc/locale.conf # CentOS/RHEL ```
Step 5: Set User Locale
```bash # Add to user profile: vim ~/.bashrc
export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8
# Or ~/.profile: vim ~/.profile
export LANG=en_US.UTF-8 export LC_ALL=en_US.UTF-8
# Apply immediately: source ~/.bashrc
# Check: locale
# For specific shell: vim ~/.zshrc export LANG=en_US.UTF-8
# System-wide bashrc: vim /etc/bash.bashrc export LANG=en_US.UTF-8 ```
Step 6: Fix SSH Locale Forwarding
```bash # SSH forwards locale from client
# Check SSH config on server: cat /etc/ssh/sshd_config | grep AcceptEnv
# Default: # AcceptEnv LANG LC_* LANGUAGE XMODIFIERS
# If locale forwarding causes issues:
# On client, disable forwarding: vim ~/.ssh/config
Host myserver SetEnv LANG= SendEnv -
# Or on server, reject certain locales: vim /etc/ssh/sshd_config
AcceptEnv LANG LC_* LANGUAGE # Remove problematic locales
# Restart SSH: systemctl restart sshd
# Or configure client to use server locale: vim ~/.ssh/config
Host myserver RequestTTY yes
# Login and set locale: ssh user@server export LANG=en_US.UTF-8 ```
Step 7: Fix Docker Container Locale
```bash # Minimal containers often lack locale
# Install locale in Dockerfile: # Debian/Ubuntu: RUN apt-get update && apt-get install -y locales RUN locale-gen en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8
# Alpine: RUN apk add --no-cache musl-locales ENV LANG=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8
# CentOS/RHEL: RUN yum install -y glibc-langpack-en ENV LANG=en_US.UTF-8
# Build image: docker build -t myimage .
# Run with locale: docker run -e LANG=en_US.UTF-8 -e LC_ALL=en_US.UTF-8 myimage
# Or add to compose: environment: - LANG=en_US.UTF-8 - LC_ALL=en_US.UTF-8 ```
Step 8: Test Locale Configuration
```bash # Test locale: locale
# Test character encoding: echo "Hello 世界" | xxd
# Test date format: date
# Test number format: printf "%.2f\n" 1234.56
# Test currency: # Depends on LC_MONETARY
# Test sort order: sort test.txt
# Test character classes: ls -l | grep [[:alpha:]]
# Test in Python: python3 -c "import locale; locale.setlocale(locale.LC_ALL, 'en_US.UTF-8'); print(locale.currency(1234.56))"
# Test in Perl: perl -e 'use POSIX; setlocale(LC_ALL, "en_US.UTF-8"); print strftime("%c", localtime());'
# Test with locale command: locale -k LC_TIME # Shows time format settings ```
Step 9: Troubleshoot Specific Issues
```bash # Issue: Locale generation fails locale-gen en_US.UTF-8 # Error: character map file not found
# Fix: Install full language support: apt install language-pack-en-base
# Issue: Perl locale warning # Fix: Install locales package: apt install locales locale-gen en_US.UTF-8
# Issue: Python locale error # Fix: Ensure locale installed and set: python3 -c "import locale; locale.setlocale(locale.LC_ALL, '')"
# Issue: MySQL locale # Check MySQL locale: mysql -e "SHOW VARIABLES LIKE '%locale%'";
# Set in MySQL config: [mysqld] lc-messages=en_US
# Issue: Postgres locale # Check: psql -c "SHOW lc_ctype;"
# Set at database creation: createdb --locale=en_US.UTF-8 mydb ```
Step 10: Monitor and Verify
```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-locale.sh #!/bin/bash
echo "=== Current Locale ===" locale
echo "" echo "=== Available Locales ===" locale -a | head -20
echo "" echo "=== Locale Config ===" cat /etc/locale.conf 2>/dev/null || cat /etc/default/locale 2>/dev/null
echo "" echo "=== Environment Variables ===" echo "LANG=$LANG" echo "LC_ALL=$LC_ALL" echo "LANGUAGE=$LANGUAGE"
echo "" echo "=== Test Locale ===" perl -e 'print "Perl OK\n"' python3 -c 'print("Python OK")' date
echo "" echo "=== Character Test ===" echo "Test: α β γ δ 中文 日本語" EOF
chmod +x /usr/local/bin/check-locale.sh
# Run: /usr/local/bin/check-locale.sh
# System locale status: localectl status
# Check if locale valid: locale -a | grep -q "en_US.utf8" && echo "OK" || echo "Missing" ```
Linux Locale Checklist
| Check | Command | Expected |
|---|---|---|
| Current locale | locale | No errors |
| Available locales | locale -a | en_US.utf8 listed |
| LANG var | echo $LANG | Set to valid locale |
| Config file | cat /etc/locale.conf | LANG configured |
| Perl test | perl -e print | No warnings |
| Date format | date | Correct format |
Verify the Fix
```bash # After fixing locale
# 1. Check locale locale // No errors, LANG set
# 2. Check available locale -a | grep en_US.utf8 // Listed
# 3. Test perl perl -e 'print "test\n"' // No warnings
# 4. Test date date // Correct format
# 5. Test characters echo "Test: 世界" // Displays correctly
# 6. Test application # Run app that uses locale // No locale errors ```
Related Issues
- [Fix Linux System Time Wrong](/articles/fix-linux-system-time-wrong)
- [Fix Linux System Service Failed](/articles/fix-linux-system-service-failed)
- [Fix Linux System Disk Full](/articles/fix-linux-system-disk-full)