ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'body' at row 1 は、絵文字や「𠮷(つちよし)」のような4バイトの文字を、3バイトまでしか扱えない文字コード(utf8mb3)の列や接続で保存しようとしたときに出るエラーです。

'\xF0...' のように \xF0 で始まっていれば、4バイトの文字です。直し方は、列(テーブル)と接続の両方を utf8mb4 にすることです。

Incorrect string value の値 文字 原因
'\xF0\x9F\x8D\xA3' 🍣(絵文字) 4バイトの文字を utf8mb3 で保存しようとした
'\xF0\xA0\xAE\xB7...' 𠮷(つちよし)などの一部の漢字 同上(絵文字以外にも4バイトの漢字がある)
'\xE3\x81\x82...' あ(日本語) 日本語を latin1 などの列に保存しようとした

確認環境:MySQL 8.0.46(Ubuntu 24.04)、PHP 8.4(PDO)、Python 3.13(PyMySQL 2.2.8・mysql-connector-python)(確認日 2026年10月10日)。Connector/J(Java)の設定は Connector/J 9.7.0 のソースの説明で確認しています。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「MySQL Incorrect string valueの直し方|絵文字・𠮷」

再現:utf8mb3 の列に絵文字と𠮷を入れる

CREATE DATABASE emojidemo CHARACTER SET utf8mb3;
CREATE TABLE post (id INT PRIMARY KEY, body VARCHAR(100));   -- DB の既定を引き継いで utf8mb3
INSERT INTO post VALUES (1, 'こんにちは①髙');
INSERT INTO post VALUES (2, '寿司🍣');
INSERT INTO post VALUES (3, '𠮷野家');
Query OK(1件目)
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'body' at row 1
ERROR 1366 (HY000): Incorrect string value: '\xF0\xA0\xAE\xB7\xE9\x87...' for column 'body' at row 1

「こんにちは①髙」は入り、🍣と𠮷はエラーになりました。①や髙(はしご高)は3バイトなので utf8mb3 でも入ります。

文字 UTF-8 のバイト数 utf8mb3 utf8mb4
あ・漢字の大半・①・髙 3 ○ ○
🍣😀などの絵文字 4 × ○
𠮷(つちよし)・𩸽(ほっけ)など一部の漢字 4 × ○

utf8mb3 は MySQL の公式マニュアルで非推奨とされ、将来のメジャーバージョンで削除される予定です。MySQL で utf8 と書くと、これは utf8mb3 の別名です。

まず4か所を確認する

文字コードは、サーバー・DB・テーブル(列)・接続の4か所で決まります。どこが utf8mb3 なのかを先に確かめます。

-- 列ごとの文字コード(utf8mb4 以外を探す)
SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'emojidemo' AND CHARACTER_SET_NAME IS NOT NULL
  AND CHARACTER_SET_NAME <> 'utf8mb4';

-- DB の既定
SELECT DEFAULT_CHARACTER_SET_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'emojidemo';

-- 今の接続
SHOW VARIABLES LIKE 'character_set_c%';
+------------+-------------+--------------------+--------------------+
| TABLE_NAME | COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME     |
+------------+-------------+--------------------+--------------------+
| post       | body        | utf8mb3            | utf8mb3_general_ci |
+------------+-------------+--------------------+--------------------+
場所 確認 utf8mb3 だと
列 information_schema.COLUMNS エラーになる(いちばん多い原因)
テーブル・DB の既定 SHOW CREATE TABLE、SCHEMATA 次に作る列が utf8mb3 になる
接続 SHOW VARIABLES LIKE 'character_set_c%' 列が utf8mb4 でもエラーになる(下で再現)
サーバーの既定 @@character_set_server MySQL 8.0 の既定は utf8mb4

列を utf8mb4 にしても、接続が utf8mb3 だとエラーになる

utf8mb4 の列に、接続を utf8mb3 にして同じ文字を入れました。

CREATE TABLE post4 (id INT PRIMARY KEY, body VARCHAR(100)) DEFAULT CHARSET=utf8mb4;
SET NAMES utf8mb3;           -- 接続を utf8mb3 にする
INSERT INTO post4 VALUES (1, '寿司🍣');
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'body' at row 1

列だけ直しても、アプリの接続設定が utf8(=utf8mb3)のままだと直りません。 接続設定は、この記事の後半の「アプリの接続設定」で確認します。

エラーにならず「?」で保存されることもある

sql_mode から STRICT_TRANS_TABLES を外している(以前の設定を引き継いだサーバーなど)と、エラーではなく警告になり、文字が ? に置き換わって保存されました。

SET SESSION sql_mode = '';
INSERT INTO post VALUES (2, '寿司🍣');
SHOW WARNINGS;
SELECT id, body, HEX(body) FROM post;
| Warning | 1366 | Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'body' at row 1 |

| id | body          | HEX(body)                                  |
|  1 | こんにちは①髙 | E38193E38293E381ABE381A1E381AFE291A0E9AB99 |
|  2 | 寿司?         | E5AFBFE58FB83F                             |   ← 3F は「?」

? に置き換わったデータは、元の文字に戻せません。エラーが出ないぶん気づきにくいので、sql_mode に STRICT_TRANS_TABLES が入っているか確認しておきます(MySQL 8.0 の既定には入っています)。

直し方:utf8mb4 に変換する

-- 1. DB の既定(次に作るテーブル用)
ALTER DATABASE emojidemo CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

-- 2. テーブルとすべての文字列の列をまとめて変換
ALTER TABLE post CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

-- 3. 確認
INSERT INTO post VALUES (2, '寿司🍣'), (3, '𠮷野家');
SELECT id, body, CHAR_LENGTH(body) AS chars, LENGTH(body) AS bytes FROM post;
| id | body          | chars | bytes |
|  1 | こんにちは①髙 |     7 |    21 |
|  2 | 寿司🍣        |     3 |    10 |   ← 🍣は4バイト
|  3 | 𠮷野家        |     3 |    10 |   ← 𠮷も4バイト
手順 注意
変換の前 バックアップを取る。大きなテーブルは変換中にロックがかかるので、時間帯を選ぶ
ALTER DATABASE 既存のテーブルは変わらない。テーブルごとに ALTER TABLE ... CONVERT TO が要る
CONVERT TO テーブル内のすべての文字列の列が変換される。列ごとに変えるなら MODIFY 列 VARCHAR(100) CHARACTER SET utf8mb4
照合順序 MySQL 8.0 の既定は utf8mb4_0900_ai_ci。以前のテーブルと比較・結合するなら、照合順序をそろえる

インデックスの長さでエラーになる場合

utf8mb4 は1文字が最大4バイトなので、インデックスに使える文字数が減ります。

CREATE TABLE k (v VARCHAR(1000), KEY (v)) DEFAULT CHARSET=utf8mb4;
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes
行フォーマット インデックスの上限 utf8mb4 で使える文字数
DYNAMIC・COMPRESSED(MySQL 8.0 の既定は DYNAMIC) 3072バイト 768文字
COMPACT・REDUNDANT(以前のテーブル) 767バイト 191文字

VARCHAR(1000) の列にインデックスを張っているなら、KEY (v(768)) のように先頭の文字数を指定するか、列の長さを見直します。VARCHAR(768) は utf8mb4 でもそのまま作れました。

アプリの接続設定

列を utf8mb4 にしたら、アプリの接続も utf8mb4 にします。utf8 と書いているところは、utf8mb3 になる可能性があります。

PHP(PDO)

$pdo = new PDO('mysql:host=localhost;dbname=emojidemo;charset=utf8mb4', $user, $pass);

確認環境で DSN の charset を変えて、🍣を保存しました。

dsn(charset指定なし)  -> utf8mb4  OK       ← サーバーの既定が utf8mb4 なので通った
dsn;charset=utf8      -> utf8mb3  SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF0\x9F\x8D\xA3' ...
dsn;charset=utf8mb4   -> utf8mb4  OK

指定なしで通るかはサーバーの設定に左右されるので、charset=utf8mb4 を明示します。

Python(PyMySQL・mysql-connector-python)

conn = pymysql.connect(host="localhost", user="app", password="...", database="emojidemo", charset="utf8mb4")
pymysql 2.2.8 charset= None -> utf8mb4 OK
pymysql 2.2.8 charset= utf8 -> utf8mb3 DataError(1366, "Incorrect string value: '\xF0\x9F\x8D\xA3' for column 'body' at row 1")

PyMySQL・mysql-connector-python とも、確認したバージョンの既定は utf8mb4 でした。以前に書いた charset="utf8" が残っていると utf8mb3 になります。

Java(Connector/J)

jdbc:mysql://localhost:3306/emojidemo?characterEncoding=UTF-8

Connector/J 9.7.0 のソースの説明では、characterEncoding も connectionCollation も指定しない場合、8.0.26 以降は utf8mb4、8.0.25 以前はサーバーの既定の文字コードを使います。8.0 系でも以前のバージョンを使っているときは、ドライバのバージョンと設定を確認します。

環境 設定
PHP(PDO) DSN に charset=utf8mb4
Python(PyMySQL) charset="utf8mb4"("utf8" は utf8mb3)
Java(Connector/J 8.0.26 以降) 既定で utf8mb4。指定するなら characterEncoding=UTF-8
Spring Boot 接続URL(spring.datasource.url)に上の Java の設定
mysql コマンド mysql --default-character-set=utf8mb4
my.cnf(サーバー全体) [mysqld] に character-set-server=utf8mb4

寿司ビール問題:照合順序にも注意

utf8mb4 にすると、照合順序によっては絵文字どうしが同じ文字として比較されます。

SELECT '🍣' = '🍺' AS utf8mb4_0900_ai_ci,
       '🍣' = '🍺' COLLATE utf8mb4_general_ci AS utf8mb4_general_ci;
| utf8mb4_0900_ai_ci | utf8mb4_general_ci |
|                  0 |                  1 |   ← general_ci では 🍣 と 🍺 が「等しい」

utf8mb4_general_ci や utf8mb4_unicode_ci では、🍣と🍺が同じと判定されました(「寿司ビール問題」と呼ばれます)。既定の utf8mb4_0900_ai_ci でも、「ハ」と「パ」「は」は等しいと判定されました(濁点・大文字小文字・ひらがなとカタカナを区別しない比較のため)。日本語を厳密に区別するなら utf8mb4_ja_0900_as_cs_ks、完全一致なら utf8mb4_bin です。ユニーク制約や検索に影響するので、MySQL 8.0 では utf8mb4_0900_ai_ci(既定)か、完全一致が必要なら utf8mb4_bin を選びます。照合順序の違いは、関連記事の照合順序の比較表で詳しく比べています。

よくある質問

Q. テーブルは utf8mb4 なのに、まだエラーになります。 A. 列ごとに utf8mb3 が残っている(ALTER TABLE ... DEFAULT CHARSET だけを変えた)か、アプリの接続が utf8mb3 です。上の「4か所を確認する」の SQL で、列と接続を確認します。

Q. 日本語(ひらがな・漢字)でもこのエラーが出ます。 A. 値が '\xE3...' で始まるなら、列が latin1 などの日本語を扱えない文字コードです。同じく utf8mb4 に変換します。

Q. すでに「?」になったデータは戻せますか。 A. 戻せません。? で保存した時点で元の文字は失われています。元のデータ(入力の記録やファイル)があれば、変換後に入れ直します。

Q. utf8mb3 のままで、絵文字だけ取り除く方法はありますか。 A. アプリ側で4バイトの文字を取り除くことはできますが、𠮷のような人名の漢字も消えてしまいます。utf8mb4 に変換するのが確実です。

まとめ

  • Incorrect string value: '\xF0...' は4バイトの文字(絵文字・𠮷など)を utf8mb3 で保存しようとしたエラー
  • 列・テーブル・DB・接続の4か所を確認する。MySQL の utf8 は utf8mb3 の別名
  • ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4 で変換する。インデックスは utf8mb4 で768文字まで
  • 接続も utf8mb4 に。PHP は charset=utf8mb4、PyMySQL は charset="utf8mb4"、Connector/J は 8.0.26 以降で既定
  • STRICT を外していると ? で保存されて戻せない。照合順序は寿司ビール問題に注意

参考・出典

確認日はいずれも 2026年10月10日です。

  • MySQL 8.0 Reference Manual「The utf8mb3 Character Set」:https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html
  • MySQL 8.0 Reference Manual「Converting Between 3-Byte and 4-Byte Unicode Character Sets」:https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-conversion.html
  • MySQL Connector/J 9.7.0 ソース(接続プロパティの説明):https://github.com/mysql/mysql-connector-j

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「MySQL Incorrect string valueの直し方|絵文字・𠮷」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?