MySQLのエラーコードとは、ERROR 1045 (28000): Access denied ... のように「番号・SQLSTATE・メッセージ」の3点で原因を示す識別子です。 1000〜1999 と 3000番台以降がサーバー側のエラー、2000番台がクライアント(接続ライブラリ)側のエラーです。番号から原因の分類がわかるので、まず番号を見て、どの層の問題かを決めると解決が早くなります。

この記事では、よく出るエラー約50件を 接続・認証/権限/構文/制約/データ/ロック/容量・設定 に分けた一覧表にし、そのうち40件以上を MySQL 8.0.46 で実際に再現したエラー全文 つきで掲載します。特に検索の多い ERROR 1045・2002・2003 は、ソケットパス・ホスト・ポート・認証プラグイン・bind-address の順に切り分けるフローで整理しました。

MySQLエラーコード早見表(よく出る順)

コード SQLSTATE メッセージ(要約) 主な原因 最初にやること
1045 28000 Access denied for user (using password: YES/NO) パスワード違い、ホスト照合違い SELECT user,host FROM mysql.user
2002 HY000 Can't connect to local MySQL server through socket サーバー停止、ソケットパス違い -h127.0.0.1 で TCP 接続を試す
2003 HY000 Can't connect to MySQL server on 'host:port' ポート違い、bind-address、FW ss -lntp | grep mysqld
1064 42000 You have an error in your SQL syntax ... near '...' 構文ミス、予約語 near の直前を見る
1062 23000 Duplicate entry 'x' for key 'k' 主キー・UNIQUE重複 既存行を確認、UPSERT
1452 23000 Cannot add or update a child row 親行がない外部キー 親を先に INSERT
1406 22001 Data too long for column 文字数超過 列を広げる・入力を検証
1366 HY000 Incorrect integer/string value 型違い、4バイト文字 型と文字コードを確認
1213 40001 Deadlock found when trying to get lock ロック順序の交差 トランザクションを再実行
1205 HY000 Lock wait timeout exceeded 長いトランザクション ロック保持者を特定
1290 HY000 running with the --xxx option read_only・secure_file_priv オプション名を読む
1142 42000 XXX command denied ... for table テーブル単位の権限不足 GRANT を追加
1040 08004 Too many connections 接続数上限 max_connections・接続プール

番号の範囲で層がわかります。 1000〜1999・3000〜は「サーバーまで届いたうえでの拒否」、2000番台は「サーバーまで届いていない」ことを示します。

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

(記載例)出典:株式会社RJC「MySQLエラーコード一覧と対処法|ERROR 1045・2002の原因別解決」

検証環境とバージョン

項目 内容
MySQL 8.0.46(Ubuntu パッケージ、ポート 7246、ソケット指定で起動)
sql_mode 8.0 既定(STRICT_TRANS_TABLES・ONLY_FULL_GROUP_BY など)

MySQL 8.0 は2026年4月にサポートが終了しています。 この記事のエラー番号と対処は、MySQL 8.4 LTS・9.7 LTS でも同じ手順で使えます。8.4 以降は mysql_native_password が既定で無効(9.x では削除)のため、古いクライアントでは認証プラグイン関連のエラー(2059 など)が出やすくなる点だけ違いがあります。本文の「実行結果」は、すべて手元の 8.0.46 で再現したものです。

エラーの読み方と perror での確認

部分 意味 使いどころ
番号(1062) MySQL 固有のエラー番号 検索・一覧表で原因を引く
SQLSTATE(23000) 標準SQLの分類。先頭2文字がクラス アプリ側で分類して処理を分ける
メッセージ 値やキー名が入った説明 どの行・列が原因かを特定

SQLSTATE の先頭2文字は、アプリで処理を分けるときに使えます。

クラス 意味 例
08 接続の例外 1040(08004)、1153(08S01)
22 データの例外 1406(22001)、1264(22003)、1292(22007)
23 整合性制約違反 1062、1452、1451、1048(すべて 23000)
28 認証エラー 1045(28000)
40 トランザクションのロールバック 1213(40001)
42 構文・権限 1064、1146(42S02)、1054(42S22)、1142

perror コマンドでサーバー側のエラー番号の定義を確認できます。

perror 1045 1213
MySQL error code MY-001045 (ER_ACCESS_DENIED_ERROR): Access denied for user '%-.48s'@'%-.64s' (using password: %s)
MySQL error code MY-001213 (ER_LOCK_DEADLOCK): Deadlock found when trying to get lock; try restarting transaction

なお perror 2002 は Illegal error code: 2002 になりました。2000番台はクライアントライブラリのエラーなので、perror の対象外です。公式リファレンスの「Client Error Message Reference」で確認します。

分類別エラーコード一覧(約50件)

「再現」列が ○ のものは、この記事の環境で実際に発生させたエラーです。

接続・認証

コード SQLSTATE メッセージ 主な原因 対処 再現
1045 28000 Access denied for user 'u'@'h' (using password: YES) パスワード違い、ホスト照合違い 下の切り分けフロー ○
1045 28000 ... (using password: NO) パスワードを送っていない -p を付ける、設定ファイル確認 ○
2002 HY000 Can't connect to local MySQL server through socket '...' (2) 停止中、ソケットパス違い 起動確認、-S か -h127.0.0.1 ○
2003 HY000 Can't connect to MySQL server on 'h:p' (111) ポートで待ち受けていない ポート・bind-address 確認 ○
2005 HY000 Unknown MySQL server host 'x' ホスト名を解決できない ホスト名・DNS・hosts を確認 ○
1130 HY000 Host 'h' is not allowed to connect 接続元に合うアカウントがない 接続元ホストでユーザー作成 perror で確認
1049 42000 Unknown database 'x' DB名違い SHOW DATABASES ○
1040 08004 Too many connections max_connections 超過 接続プール、解放漏れ確認 ○
2061 HY000 caching_sha2_password ... requires secure connection 非TLSで初回認証 TLS接続、--get-server-public-key 別記事で再現
2059 HY000 Authentication plugin '...' cannot be loaded クライアントが認証方式に未対応 ドライバ更新 公式で確認
1820 HY000 You must reset your password パスワード期限切れ ALTER USER USER() IDENTIFIED BY 別記事で再現
3118 HY000 Account is locked ACCOUNT LOCK 中 ACCOUNT UNLOCK 別記事で再現
3955 HY000 Account is blocked ... consecutive failed logins 連続失敗ロック ACCOUNT UNLOCK 別記事で再現
4031 HY000 disconnected by the server because of inactivity wait_timeout 超過 再接続、プールの検証設定 ○
2013 HY000 Lost connection to MySQL server during query 実行中の切断、タイムアウト ネットワーク・net_read_timeout 公式で確認
2006 HY000 MySQL server has gone away 切断後の再利用、巨大パケット 再接続、max_allowed_packet 公式で確認

権限

コード SQLSTATE メッセージ 主な原因 対処 再現
1044 42000 Access denied for user ... to database 'x' DB単位の権限なし GRANT ... ON db.* ○
1142 42000 CREATE command denied ... for table 'x' テーブル操作の権限なし 必要な操作だけ GRANT ○
1143 42000 command denied ... for column カラム権限なし 列を明示、権限追加 別記事で再現
1227 42000 you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) 管理権限なし 動的権限を付与 ○
1290 HY000 running with the --read-only option 読み取り専用サーバー 書き込み先(プライマリ)を確認 ○
1290 HY000 running with the --secure-file-priv option 許可外のパスへ出力 @@secure_file_priv のパスを使う ○

ユーザー作成と権限付与の手順は、別記事「MySQLユーザー作成と権限付与」で詳しく扱っています。

構文・名前

コード SQLSTATE メッセージ 主な原因 対処 再現
1064 42000 You have an error in your SQL syntax ... near '...' 綴り、予約語、カンマ near の直前を見る ○
1046 3D000 No database selected DB未選択 USE db か db.table ○
1146 42S02 Table 'db.t' doesn't exist テーブル名違い SHOW TABLES ○
1054 42S22 Unknown column 'x' in 'field list' 列名違い DESC t ○
1052 23000 Column 'id' in field list is ambiguous JOIN で同名列 テーブル.列 で修飾 ○
1050 42S01 Table 'x' already exists 二重作成 IF NOT EXISTS ○
1051 42S02 Unknown table 'db.x' ないテーブルを DROP IF EXISTS ○
1060 42S21 Duplicate column name 'x' 同名列の追加 列名変更 ○
1091 42000 Can't DROP 'x'; check that column/key exists ない索引・列の削除 SHOW INDEX ○
1136 21S01 Column count doesn't match value count 列数と値の数が違う 列リストを明示 ○
1055 42000 ... incompatible with sql_mode=only_full_group_by GROUP BY にない列 集約関数か GROUP BY に追加 ○
1242 21000 Subquery returns more than 1 row = に複数行 IN か LIMIT 1 ○
1093 HY000 You can't specify target table 'x' for update in FROM clause 更新対象を副問い合わせで参照 JOIN に書き換え ○
1305 42000 FUNCTION db.x does not exist 関数名違い・未作成 名前・DB を確認 ○
3141 22032 Invalid JSON text in argument 1 不正な JSON JSON_VALID() で事前確認 ○

制約・データ

コード SQLSTATE メッセージ 主な原因 対処 再現
1062 23000 Duplicate entry 'x' for key 't.k' 主キー・UNIQUE 重複 UPSERT、事前チェック ○
1452 23000 Cannot add or update a child row 親行がない 親を先に登録 ○
1451 23000 Cannot delete or update a parent row 子行が参照中 子を先に削除、ON DELETE ○
1048 23000 Column 'x' cannot be null NOT NULL 列に NULL 値を入れる、DEFAULT ○
3819 HY000 Check constraint 'x' is violated CHECK 制約違反 値の範囲を確認 ○
1406 22001 Data too long for column 'x' 文字数超過 列を広げる、入力検証 ○
1366 HY000 Incorrect integer value: 'abc' 型が違う値 アプリ側で型変換 ○
1366 HY000 Incorrect string value: '\xF0\x9F...' utf8mb3 列に4バイト文字 列を utf8mb4 に ○
1264 22003 Out of range value for column 'x' 型の範囲外 型を広げる ○
1292 22007 Incorrect date value: '2026-02-30' 存在しない日付 日付を検証 ○
1690 22003 BIGINT UNSIGNED value is out of range UNSIGNED の引き算で負数 CAST(... AS SIGNED) ○
3780 HY000 Referencing column and referenced column ... are incompatible 外部キーの型不一致 型・符号・照合順序をそろえる ○
1824 HY000 Failed to open the referenced table 'x' 参照先がない 親テーブルを先に作る ○

ロック・トランザクション

コード SQLSTATE メッセージ 主な原因 対処 再現
1213 40001 Deadlock found when trying to get lock ロック順序の交差 再実行、更新順をそろえる ○
1205 HY000 Lock wait timeout exceeded 他トランザクションが保持 保持者を特定、短く分割 ○
1175 HY000 You are using safe update mode キーなし UPDATE/DELETE WHERE にキー列 ○

容量・設定

コード SQLSTATE メッセージ 主な原因 対処 再現
1153 08S01 Got a packet bigger than 'max_allowed_packet' bytes 巨大な SQL・BLOB max_allowed_packet を上げる ○
1118 42000 Row size too large ... 65535 VARCHAR 合計が大きすぎ TEXT へ変更 ○
1071 42000 Specified key was too long; max key length is 3072 bytes 索引が長すぎ プレフィックス長を短く ○
1114 HY000 The table 'x' is full ディスク・一時領域不足 容量確認 公式で確認

ERROR 1045・2002・2003 の切り分けフロー

flowchart TD
    A[接続エラー] --> B{エラー番号}
    B -->|2002| C[ソケット接続で失敗]
    B -->|2003| D[TCPで失敗]
    B -->|2005| E[ホスト名を解決できない]
    B -->|1045| F[サーバーには届いた・認証で拒否]
    C --> C1{サーバーは起動している?}
    C1 -->|いいえ| C2[起動してエラーログを見る]
    C1 -->|はい| C3[@@socket と -S のパスを合わせる / -h127.0.0.1 で TCP に]
    D --> D1{ポートで待ち受けている?}
    D1 -->|いいえ| D2[port / bind-address / skip-networking を確認]
    D1 -->|はい| D3[ファイアウォール・Docker のポート公開を確認]
    F --> F1{using password: NO?}
    F1 -->|はい| F2[-p を付ける / 設定ファイルを確認]
    F1 -->|いいえ| F3[同名ユーザーの host 違い・パスワード・認証プラグインを確認]

ERROR 2002:ソケットパスの違い

# 存在しないソケットを指定
mysql -uroot -S /tmp/nosuch.sock -e "SELECT 1"
# -h localhost は TCP ではなく既定のソケットを使う
mysql -uroot -h localhost -P 7246 -e "SELECT 1"
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/nosuch.sock' (2)
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

-h localhost はポートを指定してもソケット接続になります。 2つ目はサーバーが別のソケット(/tmp/t124my/mysql.sock)で動いているのに、クライアントが既定の /var/run/mysqld/mysqld.sock を探したため失敗しました。括弧内の (2) は OS のエラー番号で「ファイルがない」という意味です。

対処 コマンド
サーバー側のソケットパスを確認 SELECT @@socket;(接続できる別経路で)
ソケットを明示する mysql -S /tmp/t124my/mysql.sock
TCP で接続する mysql -h 127.0.0.1 -P 3306
設定ファイルでそろえる [client] と [mysqld] の socket= を同じにする

ERROR 2003:ポートと bind-address

mysql -uroot -h 127.0.0.1 -P 7249 -e "SELECT 1"
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:7249' (111)

(111) は「接続拒否(そのポートで誰も待ち受けていない)」です。タイムアウトする場合は (110) になり、ファイアウォールなどで通信が届いていない可能性が高くなります。

SELECT @@port, @@bind_address, @@skip_networking;

今回の環境では @@bind_address は 127.0.0.1 でした。この設定では同じマシンからしか TCP 接続できません。 別のマシンやコンテナの外から接続するには、bind-address = 0.0.0.0(または特定のIP)に変えて再起動し、接続元に合わせたユーザー('app'@'10.0.1.%' など)を用意します。

ERROR 1045:認証で拒否された

ERROR 1045 (28000): Access denied for user 'app'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'app'@'localhost' (using password: NO)

1045 はサーバーまで届いている証拠です。 ネットワークではなくアカウント側を確認します。

チェック SQL・ポイント
どのアカウントに照合されたか エラー文の 'app'@'localhost' を読む
同名ユーザーが複数ホストにないか SELECT user, host, plugin FROM mysql.user WHERE user='app';
パスワードを送ったか using password: NO なら -p や設定ファイルの password= を確認
認証プラグイン・ロック plugin・account_locked・password_expired 列

今回の環境では、ユーザーを 'remote'@'10.9.9.%' だけで作って 127.0.0.1 から接続すると、1130 ではなく 1045('remote'@'localhost')になりました。接続元のホスト名が解決できる環境では、「接続元に合うアカウントがない」場合も 1045 として表示されることがあります。

root のパスワードがわからなくなったときの再設定手順(--skip-grant-tables や --init-file)は、公式ドキュメント「How to Reset the Root Password」に沿って行ってください。

よく出るエラーの再現と直し方

ここからは、次のテーブルを使って再現しています。

CREATE DATABASE errdb;
USE errdb;
CREATE TABLE members (
  id INT PRIMARY KEY,
  email VARCHAR(20) NOT NULL UNIQUE,
  name VARCHAR(10),
  age TINYINT UNSIGNED,
  joined DATE,
  CHECK (age < 150)
);
CREATE TABLE orders (
  id INT PRIMARY KEY AUTO_INCREMENT,
  member_id INT NOT NULL,
  qty INT,
  FOREIGN KEY (member_id) REFERENCES members(id)
);
CREATE TABLE stock (id INT PRIMARY KEY, qty INT);
INSERT INTO members VALUES (1,'a@example.com','Aoki',30,'2026-01-01'),
                           (2,'b@example.com','Baba',40,'2026-02-01');
INSERT INTO orders (member_id, qty) VALUES (1, 2);
INSERT INTO stock VALUES (1,10),(2,20);

1062:重複キー

INSERT INTO members VALUES (3,'a@example.com','Chiba',20,'2026-03-01');
ERROR 1062 (23000): Duplicate entry 'a@example.com' for key 'members.email'

8.0 からはキー名が テーブル名.キー名 で表示されるので、どの UNIQUE に当たったかがすぐわかります。 「あれば更新、なければ追加」にしたいときは UPSERT を使います(詳細は別記事「SQL UPSERTの書き方」)。

INSERT INTO members VALUES (3,'a@example.com','Chiba',20,'2026-03-01') AS new
ON DUPLICATE KEY UPDATE name = new.name;

1452・1451:外部キー

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`errdb`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`))
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`errdb`.`orders`, CONSTRAINT `orders_ibfk_1` FOREIGN KEY (`member_id`) REFERENCES `members` (`id`))
エラー 起きた操作 直し方
1452 orders に存在しない member_id=99 を INSERT 親(members)を先に登録する
1451 注文が残っている members.id=1 を DELETE 子を先に削除、または ON DELETE CASCADE を設計で検討

データ移行で SET FOREIGN_KEY_CHECKS=0; を使った場合は、移行後に =1 へ戻し、LEFT JOIN ... WHERE 親.id IS NULL で孤立行がないかを確認します。

1406・1366・1264・1292:値が列に合わない

ERROR 1406 (22001): Data too long for column 'name' at row 1
ERROR 1366 (HY000): Incorrect integer value: 'abc' for column 'age' at row 1
ERROR 1264 (22003): Out of range value for column 'age' at row 1
ERROR 1292 (22007): Incorrect date value: '2026-02-30' for column 'joined' at row 1

8.0 の既定 sql_mode には STRICT_TRANS_TABLES が含まれるため、合わない値は切り捨てずにエラーになります。 1264 は TINYINT UNSIGNED(0〜255)に 300 や -1 を入れたときに出ました。sql_mode を緩めると値が丸められて保存されるので、列の型か入力検証で直すのが確実です。

1366:4バイト文字(絵文字)

CREATE TABLE notes3 (body VARCHAR(20) CHARACTER SET utf8mb3);
INSERT INTO notes3 VALUES ('OK😀');
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x98\x80' for column 'body' at row 1

\xF0 で始まる値は4バイト文字です。 utf8mb3(旧 utf8)は3バイトまでしか保存できないため、列を utf8mb4 に変更します。次の ALTER の後は同じ INSERT が成功し、HEX(body) は 4F4BF09F9880 になりました。

ALTER TABLE notes3 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

なお検証中、mysql -e をロケール未設定のシェルから実行したところ character_set_client が latin1 になり、エラーにならずに崩れた値が保存されました。クライアント側は --default-character-set=utf8mb4 を指定すると確実です。 文字化けの見分け方は別記事「文字化けの原因と直し方」を参照してください。

1064:構文エラー

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC * FROM members' at line 1

near '...' に表示された文字列の「直前」が原因の場所です。 よくある原因は次のとおりです。

原因 例 直し方
綴り SELEC SELECT
予約語を名前に使う CREATE TABLE order (...) `order` とバッククォートで囲む
末尾のカンマ SELECT id, name, FROM t 最後のカンマを消す
8.0 で廃止された書き方 GRANT ... IDENTIFIED BY CREATE USER と分ける

1146・1054・1052:名前の間違い

ERROR 1146 (42S02): Table 'errdb.member' doesn't exist
ERROR 1054 (42S22): Unknown column 'nam' in 'field list'
ERROR 1052 (23000): Column 'id' in field list is ambiguous

Linux では既定でテーブル名の大文字・小文字が区別されます(lower_case_table_names=0)。1052 は JOIN で両方のテーブルに id があるときに出るので、members.id のように修飾します。

1055:ONLY_FULL_GROUP_BY

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'errdb.orders.qty' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
-- 直す前
SELECT member_id, qty FROM orders GROUP BY member_id;
-- 直した後(集約するか、GROUP BY に含める)
SELECT member_id, SUM(qty) AS total_qty FROM orders GROUP BY member_id;

どの行の qty を返すかが決まらないため、エラーになります。 どれでもよい場合は ANY_VALUE(qty) も使えます。

1093:更新対象を副問い合わせで参照

ERROR 1093 (HY000): You can't specify target table 'members' for update in FROM clause
-- 直す前
UPDATE members SET age = age + 1
WHERE id IN (SELECT id FROM members WHERE age > 35);
-- 直した後(JOIN に書き換え):検証環境で2行更新
UPDATE members m
JOIN (SELECT id FROM members WHERE age > 35) t ON m.id = t.id
SET m.age = m.age + 1;

1213・1205:デッドロックとロック待ちタイムアウト

2つのセッションで stock の id=1 と id=2 を逆の順番で更新すると、片方が 1213 になりました。

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

片方のセッションがロックを持ったまま、もう片方が innodb_lock_wait_timeout=3 で待つと 1205 になりました(既定値は 50 秒)。

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
項目 1213 デッドロック 1205 ロック待ちタイムアウト
起きること InnoDB が片方を自動でロールバック 待った側の文だけがエラー
トランザクション 全体がロールバック済み 既定では文だけ失敗、トランザクションは継続
対処 トランザクション全体を再実行 ロック保持者を特定し、トランザクションを短く
調べ方 SHOW ENGINE INNODB STATUS sys.innodb_lock_waits

1205 の後はトランザクションが続いているので、ROLLBACK するか再実行するかをアプリ側で明示します。 再現手順とログの読み方は別記事「デッドロックの原因と対策」で詳しく扱っています。

1290:read_only と secure_file_priv

ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

1290 はメッセージ内のオプション名で原因が決まります。 read_only はレプリカや切り替え中のサーバーに書き込んだときに出るので、接続先を確認します。secure_file_priv は SELECT ... INTO OUTFILE や LOAD DATA INFILE で許可外のパスを使ったときに出ます。今回の環境の値は /var/lib/mysql-files/ でした。CSV の取り込み全般は別記事「MySQL CSVインポート」を参照してください。

1040・4031・1153:接続数・タイムアウト・パケット

ERROR 1040 (08004): Too many connections
ERROR 4031 (HY000): The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.
ERROR 1153 (08S01): Got a packet bigger than 'max_allowed_packet' bytes
エラー 再現した条件 対処
1040 max_connections=2 で一般ユーザーが3本目を接続 接続プールの上限、解放漏れ、max_connections
4031 wait_timeout=2 のセッションで4秒放置後に実行 プールの接続検証、wait_timeout の調整
1153 max_allowed_packet=1MB で約2MBの SQL を送信 サーバーとクライアント両方の値を上げる

1040 の状態でも root では接続できました。CONNECTION_ADMIN(または SUPER)を持つユーザー用に1本分の予備枠があるため、管理者がログインして原因を調べられます。4031 は 8.0.24 以降のメッセージで、それ以前のクライアントでは 2013 や 2006 として表示されることがあります。

Docker・WSL・macOS(Homebrew)別の確認コマンド

このセクションのコマンドは、各環境の公式ドキュメントに沿って記載したもので、この記事の検証環境では実行していません。

環境 起動確認 接続のポイント エラーログ
Linux(deb/apt) systemctl status mysql 既定ソケット /var/run/mysqld/mysqld.sock /var/log/mysql/error.log
Linux(rpm/dnf) systemctl status mysqld 既定ソケット /var/lib/mysql/mysql.sock /var/log/mysqld.log
Docker(公式イメージ) docker ps、docker logs <コンテナ名> ホストからは -h 127.0.0.1 -P <公開ポート> 標準出力(docker logs)
WSL2 sudo service mysql status Windows 側からは 127.0.0.1 で接続 Linux(deb)と同じ
macOS(Homebrew) brew services list 既定ソケット /tmp/mysql.sock $(brew --prefix)/var/mysql/<ホスト名>.err

Docker でよくある組み合わせ

# コンテナ内で接続(ソケット)
docker exec -it db mysql -uroot -p

# ホストから接続:localhost ではなく 127.0.0.1 を指定(2002 回避)
mysql -h 127.0.0.1 -P 3306 -uroot -p

# ポート公開を確認(2003 の切り分け)
docker port db

ホストから -h localhost で接続するとソケットを探して 2002 になります。 Docker では -h 127.0.0.1 と -p 3306:3306 のポート公開をセットで確認します。コンテナ間の接続では、ホスト名にサービス名(例:db)を使います。

エラーログの場所と見方

まずは SQL でログの場所を確認します。

SELECT @@log_error, @@log_error_verbosity, @@log_timestamps;

検証環境では /tmp/t124my/err.log、2、UTC でした。log_timestamps が UTC の場合、日本時間より9時間前の時刻で記録されます。

2026-10-01T15:55:26.780393Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.46-0ubuntu0.24.04.4'  socket: '/tmp/t124my/mysql.sock'  port: 7246  (Ubuntu).
2026-10-01T16:01:29.283836Z 132 [Note] [MY-010926] [Server] Access denied for user 'app'@'localhost' (using password: YES)

各行は「時刻(Z は UTC)・スレッドID・重要度(System/Warning/Note)・ログ用コード(MY-xxxxxx)・サブシステム・本文」の順です。

ログイン失敗(Access denied)は log_error_verbosity=3 のときだけ Note として記録されます。 既定の 2 では記録されないので、1045 の原因調査中だけ一時的に 3 に上げると便利です。

SET GLOBAL log_error_verbosity = 3;   -- 調査後は 2 に戻す

8.0.22 以降は、エラーログを SQL で読むこともできます。

SELECT LOGGED, PRIO, ERROR_CODE, LEFT(DATA, 80) AS DATA
FROM performance_schema.error_log
ORDER BY LOGGED DESC LIMIT 3;

実行すると、上のログファイルと同じ内容が LOGGED(セッションのタイムゾーンで表示)・PRIO・ERROR_CODE・DATA の列で返りました。

どのエラーが何回起きたかは、performance_schema の集計表で確認できます。 アプリが出しているエラーの傾向をつかむのに役立ちます。

SELECT ERROR_NUMBER, ERROR_NAME, SQL_STATE, SUM_ERROR_RAISED
FROM performance_schema.events_errors_summary_global_by_error
WHERE SUM_ERROR_RAISED > 0
ORDER BY SUM_ERROR_RAISED DESC LIMIT 5;

検証環境では、上位に ER_ACCESS_DENIED_ERROR(1045、9回)や ER_TABLEACCESS_DENIED_ERROR(1142、5回)など、この記事で再現したエラーが並びました。

よくある質問

Q. ERROR 2002 と 2003 はどう違いますか? A. 2002 はソケット(同じマシン内のファイル)での接続失敗、2003 は TCP(ホスト名・IPとポート)での接続失敗です。-h localhost はソケット、-h 127.0.0.1 は TCP になるので、片方で失敗したらもう片方を試すと原因を絞り込めます。

Q. ERROR 1045 でパスワードは合っているはずなのに入れません。 A. 同じユーザー名で localhost と % の両方のアカウントがあり、想定と違う方に照合されている可能性があります。エラー文の 'ユーザー'@'ホスト' と SELECT user, host FROM mysql.user を見比べてください。

Q. 1213 と 1205 はどちらもリトライすればよいですか? A. 1213 はトランザクション全体がロールバック済みなので、最初から再実行します。1205 は既定ではその文だけが失敗しているため、ROLLBACK してから再実行するか、待ちの原因を取り除いてから続行します。

Q. MySQL 8.4 や 9.7 でもエラー番号は同じですか? A. この記事で扱った番号とメッセージは、8.4・9.7 でも同じ意味で使われています。新しい版ではメッセージの文言が少し変わることがあるので、正確な文言は各版の「Server Error Message Reference」で確認してください。

まとめ

  • 番号で層を判断:1000〜1999・3000〜はサーバー、2000番台はクライアント(届いていない)
  • 2002 はソケット、2003 は TCP。-h localhost と -h 127.0.0.1 を切り替えて切り分ける
  • 1045 は届いたうえでの拒否。'ユーザー'@'ホスト' の照合とパスワードを確認
  • 制約系(1062・1452・1451・1048)は SQLSTATE 23000 でまとめて扱える
  • 1213 は全体を再実行、1205 は ROLLBACK を明示
  • エラーログは @@log_error、SQL なら performance_schema.error_log
  • 8.4・9.7でも同じ手順で使える。サーバーのエラーは perror で定義を確認

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

(記載例)出典:株式会社RJC「MySQLエラーコード一覧と対処法|ERROR 1045・2002の原因別解決」

株式会社RJCでは、MySQLのエラーの読み解き方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社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で一緒に開発しながら、 成長を楽しみませんか?