This MySQL client error occurs when the client library cannot load the required character set definition files from disk. The error typically indicates that the character set files are missing, corrupted, or inaccessible, often due to incomplete MySQL installation, missing /usr/share/mysql/charsets directory, or incorrect file permissions.
The CR_CANT_READ_CHARSET (2019) is a MySQL client-side error that occurs during the connection initialization phase, before any network communication with the server. The MySQL client library needs to load character set definition files from disk to properly encode and decode text data. Key aspects of this error: 1. **Client-Side Error**: This error originates in the client library (libmysqlclient), not the MySQL server. It happens during connection setup when the client tries to initialize the requested character set (like utf8, utf8mb4, latin1, etc.). 2. **Character Set Files**: MySQL stores character set definitions in XML files located in the charsets directory, typically at `/usr/share/mysql/charsets/`. These files contain encoding rules, collation information, and character mapping tables. 3. **Common Trigger**: The error message often includes the path where the client attempted to locate the charset files: "Can't initialize character set utf8mb4 (path: /usr/share/mysql/charsets/)" 4. **Installation Issue**: This is most commonly seen in minimal or containerized installations where the charset files were not included, or after OS upgrades that remove "unnecessary" files. The error prevents any database connection from being established, making it a critical blocker for applications.
First, check if the MySQL charset files are present on your system:
# Check if charsets directory exists
ls -la /usr/share/mysql/charsets/
# Common charset file locations:
# /usr/share/mysql/charsets/
# /usr/share/mysql-8.0/charsets/
# /usr/local/mysql/share/charsets/
# /opt/mysql/share/charsets/
# List charset files
ls /usr/share/mysql/charsets/*.xml
# Should see files like:
# utf8.xml
# utf8mb4.xml
# latin1.xml
# Index.xml
# and others
# Check file permissions
ls -la /usr/share/mysql/charsets/utf8mb4.xml
# Should be readable (typically 644 or 755)If the directory or files are missing, proceed to reinstall the MySQL client package.
Install or reinstall the MySQL client package to restore missing charset files:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install --reinstall mysql-client
# or for MySQL 8.0
sudo apt-get install --reinstall mysql-client-8.0
# or for community version
sudo apt-get install --reinstall mysql-community-client
# Verify charsets directory after installation
ls -la /usr/share/mysql/charsets/
# Red Hat/CentOS/Rocky Linux
sudo yum reinstall mysql-community-client
# or
sudo dnf reinstall mysql-community-client
# Verify installation
rpm -ql mysql-community-client | grep charsets
# macOS with Homebrew
brew reinstall mysql-client
# or
brew reinstall mysql
# Verify
ls -la /usr/local/opt/mysql/share/charsets/After reinstalling, verify the charset files are present and readable.
Configure the client to use the correct charset directory location:
# Find where MySQL client expects charset files
mysql --help | grep "character-sets-dir"
# If files exist but in different location, set environment variable
export MYSQL_CHARSET_DIR=/usr/share/mysql/charsets
# Make permanent in bash profile
echo 'export MYSQL_CHARSET_DIR=/usr/share/mysql/charsets' >> ~/.bashrc
source ~/.bashrc
# For system-wide setting
echo 'export MYSQL_CHARSET_DIR=/usr/share/mysql/charsets' | sudo tee -a /etc/environmentIn application code, specify charset directory:
// PHP - Set charset directory in PDO options
$options = [
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
];
$dsn = "mysql:host=localhost;dbname=mydb;charset=utf8mb4";
$pdo = new PDO($dsn, $user, $pass, $options);
// Or in php.ini
mysql.default_charset = utf8mb4# Python - Ensure proper character set in connection
import mysql.connector
config = {
'host': 'localhost',
'user': 'root',
'password': 'password',
'database': 'mydb',
'charset': 'utf8mb4',
'use_unicode': True
}
connection = mysql.connector.connect(**config)If running MySQL client in Docker, ensure charset files are included:
# Option 1: Install full MySQL client package in Dockerfile
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y \
default-mysql-client \
&& rm -rf /var/lib/apt/lists/*
# Verify charsets are installed
RUN ls -la /usr/share/mysql/charsets/# Option 2: Copy charset files from MySQL image
FROM php:8.2-fpm
# Copy charsets from official MySQL image
COPY --from=mysql:8.0 /usr/share/mysql/charsets /usr/share/mysql/charsets
# Verify
RUN ls -la /usr/share/mysql/charsets/# Docker Compose - volume mount charset files
version: '3.8'
services:
app:
image: php:8.2-fpm
volumes:
- /usr/share/mysql/charsets:/usr/share/mysql/charsets:ro
environment:
- MYSQL_CHARSET_DIR=/usr/share/mysql/charsetsFor existing containers:
# Install charset files in running container
docker exec -it container_name bash
apt-get update && apt-get install -y mysql-client
ls /usr/share/mysql/charsets/
exit
# Commit changes to image
docker commit container_name my-app:with-mysql-charsetsEnsure proper permissions on charset files and directories:
# Check directory permissions
ls -ld /usr/share/mysql/
ls -ld /usr/share/mysql/charsets/
# Directory should be readable and executable
sudo chmod 755 /usr/share/mysql/charsets/
# Check file permissions
ls -la /usr/share/mysql/charsets/
# Files should be readable
sudo chmod 644 /usr/share/mysql/charsets/*.xml
# Check ownership
sudo chown -R root:root /usr/share/mysql/charsets/
# Check SELinux contexts (Red Hat/CentOS)
ls -Z /usr/share/mysql/charsets/
# Restore SELinux contexts if needed
sudo restorecon -Rv /usr/share/mysql/charsets/
# Check if current user can read files
cat /usr/share/mysql/charsets/utf8mb4.xml > /dev/null
echo $? # Should return 0 if readable
# Test from application user context
sudo -u www-data cat /usr/share/mysql/charsets/utf8mb4.xml > /dev/null
sudo -u nginx cat /usr/share/mysql/charsets/utf8mb4.xml > /dev/nullAs a workaround, use a simpler charset or let MySQL use defaults:
// PHP - Don't specify charset, let server decide
$dsn = "mysql:host=localhost;dbname=mydb";
$pdo = new PDO($dsn, $user, $pass);
// Or explicitly use latin1 (more widely available)
$dsn = "mysql:host=localhost;dbname=mydb;charset=latin1";
$pdo = new PDO($dsn, $user, $pass);
// Then set charset after connection
$pdo->exec("SET NAMES utf8mb4");# Python - Let connection use server default
import mysql.connector
config = {
'host': 'localhost',
'user': 'root',
'password': 'password',
'database': 'mydb'
# Don't specify charset initially
}
connection = mysql.connector.connect(**config)
# Set charset after connection
connection.cmd_query("SET NAMES utf8mb4")// Node.js - Use server default charset
const mysql = require('mysql2/promise');
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb'
// charset: 'utf8mb4' // Comment out to use server default
});
// Set charset after connection
await connection.query("SET NAMES utf8mb4");Check for version mismatches between client library and expected charset files:
# Check MySQL client version
mysql --version
# Check installed client library version
ldconfig -p | grep mysql
# Check which libmysqlclient is being used
ldd $(which mysql) | grep mysql
# For PHP, check MySQL client library version
php -i | grep "Client API version"
# For Python
python -c "import mysql.connector; print(mysql.connector.__version__)"
# Update to latest client library
# Ubuntu/Debian
sudo apt-get update
sudo apt-get upgrade mysql-client libmysqlclient-dev
# Red Hat/CentOS
sudo yum update mysql-community-client mysql-community-libs
# Verify charset files after update
ls -la /usr/share/mysql/charsets/For PHP applications:
# Rebuild PHP MySQL extension
sudo apt-get install --reinstall php-mysql
# or
sudo pecl install mysql
# Restart PHP-FPM
sudo systemctl restart php8.2-fpm
# Verify
php -m | grep mysqlThe CR_CANT_READ_CHARSET (2019) error has several advanced considerations:
1. Character Set Evolution: MySQL has deprecated utf8 (utf8mb3) in favor of utf8mb4. Modern applications should always use utf8mb4 for full Unicode support including emojis and special characters. However, older charset files may not include utf8mb4 definitions.
2. Static vs Dynamic Linking: Applications statically linked against libmysqlclient embed charset data at compile time, while dynamically linked applications load charset files at runtime. This error only affects dynamically linked clients.
3. Minimal Installation Issues: Cloud providers and container base images often use minimal MySQL client packages (mysql-client-core) that exclude charset files to save space. Production applications should use full packages or explicitly include charset files.
4. Character Set Directory Priority: MySQL searches for charset files in this order:
- Path specified by --character-sets-dir command-line option
- MYSQL_CHARSET_DIR environment variable
- Compiled-in default path (typically /usr/share/mysql/charsets/)
- Path relative to MySQL base directory
5. Custom Character Sets: If using custom character sets or collations, ensure the XML definition files are properly installed and validated against MySQL schema.
6. Performance Implications: Character set initialization happens once per connection. If charset files are on slow storage (network mount), connection establishment may be delayed.
7. Security Hardening: In security-hardened environments with AppArmor or SELinux, the MySQL client process may be denied read access to charset files. Check audit logs and adjust security policies accordingly.
8. Alternative Solutions: For containerized applications where installing charset files is problematic, consider:
- Using MariaDB client libraries which handle charsets differently
- Building MySQL from source with embedded charset data
- Using mysqlnd (MySQL native driver for PHP) which doesn't require external charset files
9. CloudLinux and alt-php: Users of CloudLinux with alt-php may encounter this error after PHP updates. Ensure alt-php-mysql-reconfigure is run after updates to properly configure charset paths.
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
ERROR 1040: Too many connections
How to fix "ERROR 1040: Too many connections" in MySQL