Skip to main content

Fixed: Accented Letters Disappear When Typed into the mysql Client in a Docker Container

· 8 min read
Jagdish Kumawat
Founder @ Dewiride

I typed SELECT 'café' into the mysql client inside the official MySQL Docker container, and the client showed 'caf'. The é never appeared on screen and never reached MySQL, and there was no error at all. The container runs without a locale, so the client only accepts plain ASCII. One extra flag on docker compose exec fixes it.

What I Was Doing​

I was writing How to Check the MySQL Character Set and Collation against the local MySQL 9.7 container from How to Run MySQL in Docker with Docker Compose. To show how MySQL counts characters and bytes, I opened the client the usual way (How to Connect to MySQL in a Docker Container with the mysql Client):

Terminal
docker compose exec mysql mysql --user=inventory_app --password inventory

and typed this query, with an accented é in café:

mysql>
SELECT 'café' AS word, CHAR_LENGTH('café') AS characters, LENGTH('café') AS bytes;

What I Expected​

café has 4 characters. In UTF-8, é takes 2 bytes, so I expected café, 4 and 5.

What I Got​

As I typed, the é simply didn't appear. The client ran what it had received:

Output
mysql> SELECT 'caf' AS word, CHAR_LENGTH('caf') AS characters, LENGTH('caf') AS bytes;
+------+------------+-------+
| word | characters | bytes |
+------+------------+-------+
| caf | 3 | 3 |
+------+------------+-------+
1 row in set (0.000 sec)

A terminal where the mysql client in the MySQL container shows SELECT 'caf' instead of the typed 'café', and the result is caf with 3 characters and 3 bytes.

No warning, no error. In a real INSERT, the letter would be silently missing from your data.

What I Checked​

Forcing a Unicode connection didn't help. I opened the client again with --default-character-set=utf8mb4, the option MySQL documents for "the default character set for the client and connection", and typed the same query. The result was identical: 'caf', 3, 3. So the problem was in the typing, before anything was sent to MySQL.

The container's locale. A locale tells programs which language and character encoding to use. The container has none:

Terminal
docker compose exec mysql locale
Output
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

LANG is empty, so everything falls back to POSIX, a locale that only knows plain ASCII. The image does include a UTF-8 locale, though:

Terminal
docker compose exec mysql locale -a
Output
C
C.utf8
POSIX

What the client does with the locale. MySQL's manual on connection character sets says each client "can autodetect which character set to use based on the operating system setting, such as the value of the LANG or LC_ALL locale environment variable on Unix systems". With no locale, the client chose latin1. The client's status command showed it:

Output (status in the default client, shortened)
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: latin1
Conn. characterset: latin1

Other people hit the same thing. In the official image's issue tracker (docker-library/mysql#131), users who couldn't type non-ASCII text report that setting the container's locale to UTF-8 fixed it.

A way to set the locale for one command. docker compose exec has -e, --env to "Set environment variables" for the command it runs.

Why It Happens​

The official MySQL image doesn't set a locale, so every program in the container runs under POSIX. The mysql client reads your keystrokes through a line-editing library that follows the locale. Under POSIX, a multi-byte character like é (two bytes in UTF-8) isn't a valid character, so it's dropped. The client also picks latin1 for the connection.

--default-character-set=utf8mb4 changes only the connection, not how your typing is read, which is why it wasn't enough on its own.

The Fix​

Start the client with a UTF-8 locale. Add -e LANG=C.utf8 (the UTF-8 locale that locale -a listed) before the service name:

Terminal
docker compose exec -e LANG=C.utf8 mysql mysql --user=inventory_app --password inventory

-e LANG=C.utf8 sets LANG for this one client session inside the container. Nothing else in the container changes, and MySQL itself keeps running untouched. The command works unchanged in bash, zsh and PowerShell.

After the Fix​

The same query, typed the same way:

Output
mysql> SELECT 'café' AS word, CHAR_LENGTH('café') AS characters, LENGTH('café') AS bytes;
+-------+------------+-------+
| word | characters | bytes |
+-------+------------+-------+
| café | 4 | 5 |
+-------+------------+-------+
1 row in set (0.000 sec)

é arrives, MySQL counts 4 characters stored in 5 bytes, and the client switched itself to Unicode without any extra option:

Output (status, shortened)
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4

A terminal where the mysql client started with -e LANG=C.utf8 accepts 'café', returns 4 characters and 5 bytes, and status shows utf8mb4 for the server, database, client and connection.

Common Mistakes​

MistakeWhat happensDo this instead
Adding only --default-character-set=utf8mb4Typed accents are still droppedAdd -e LANG=C.utf8 to docker compose exec
Using a locale the image doesn't have, such as en_US.UTF-8It doesn't fix the problemUse a locale from locale -a, here C.utf8
Trusting a test that only uses English textThe problem stays hidden until real data arrivesTest with café, naïve or an emoji

Troubleshooting​

SymptomLikely causeFix
Accented letters or emoji vanish as you typeThe container's locale is POSIXStart the client with -e LANG=C.utf8
status shows Client characterset: latin1The client autodetected latin1 from the empty localeSame fix; status then shows utf8mb4
The fix works for you but a teammate still loses lettersThey opened the client without -e LANG=C.utf8Share the full command, for example in the project's README

FAQ​

Does this affect my application?​

No. An application connects to MySQL through its own driver, over the network, with its own character set setting. It doesn't use the client inside the container or the container's locale. This problem only affects what you type into the mysql client inside the container.

Is the data already in my database damaged?​

Only text that was typed this way is affected: the dropped letters are simply missing from those rows. Text written by your applications isn't affected.

Can I use another UTF-8 locale, such as en_US.UTF-8?​

Only if the image has it. I tried -e LANG=en_US.UTF-8, and the é was still dropped, because locale -a lists only C, C.utf8 and POSIX in this image. C.utf8 is the one to use.

Conclusion​

The mysql client inside the official MySQL container runs without a locale, so it silently drops non-ASCII characters as you type them and talks to MySQL in latin1. Starting it with docker compose exec -e LANG=C.utf8 … fixes both: accents and emoji arrive intact, and the connection switches to utf8mb4.

Additional Resources​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.