【完全版】MySQL「ERROR 1045 (28000): Access denied」の原因と対処法

【完全版】MySQL「ERROR 1045 (28000): Access denied」の原因と対処法

MySQL/MariaDBに接続しようとして、以下のエラーで弾かれることはないですか?

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'app_user'@'192.168.1.100' (using password: YES)
ERROR 1045 (28000): Access denied for user ''@'localhost' (using password: NO)
SQLSTATE[HY000] [1045] Access denied for user 'user'@'host'

「ユーザー名かパスワードが違います」を意味する MySQL のエラーですが、実際の原因は10種類以上あり、パスワードを正しく入力していてもこのエラーが出るケースが頻発します。

  • パスワードは合っているはずなのに接続できない
  • 別のマシンからは接続できないが、サーバー上では成功する
  • MySQL 8 にアップグレードしたら既存アプリが繋がらなくなった
  • Docker MySQL コンテナに root で入れない
  • 新規ユーザーを作ったのに接続失敗する
  • AWS RDS で接続失敗する
  • 「(using password: NO)」と表示される

本記事では、MySQL ERROR 1045 のすべての原因と対処法を、現場で即使えるトラブルシューティング手順として整理します。MySQL認証の仕組みから、'user'@'host'の意味、認証プラグイン(caching_sha2_password / mysql_native_password)の違い、root パスワードリセット手順、Docker・AWS RDS対応、PHP/Python/Javaからの接続まで完全網羅。この1本でMySQL認証エラーの悩みが全て解決します。


目次

結論:今すぐ試すべき3ステップ

時間がない方向けに、まず試すべき手順を示します。

ステップ1:エラーメッセージから情報を読み取る

ERROR 1045 (28000): Access denied for user 'app_user'@'192.168.1.100' (using password: YES)
                                            ↑           ↑                    ↑
                                          ユーザー名    接続元IP            パスワード入力有無

この情報を元に切り分けます。

ステップ2:MySQL サーバー上でユーザー存在確認

-- root で MySQL に接続して
mysql -u root -p

-- ユーザーとホスト指定の組み合わせを確認
SELECT user, host FROM mysql.user;

ステップ3:該当ユーザーのパスワードを再設定

-- ユーザーが存在する場合
ALTER USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'new_password';

-- ユーザーが存在しない場合(新規作成)
CREATE USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'new_password';
GRANT ALL PRIVILEGES ON dbname.* TO 'app_user'@'192.168.1.100';
FLUSH PRIVILEGES;

それでも解決しない場合は、以下の詳細な原因分析へ進んでください。


まず押さえる:MySQL認証の仕組み

MySQLの認証エラーを理解するには、'user'@'host'というユーザー識別の仕組みを知る必要があります。

MySQLのユーザーは「ユーザー名+接続元ホスト」のペア

OracleやPostgreSQLと違い、MySQLは「ユーザー名」だけでなく**「どこから接続するか」もセット**でユーザーを管理します。

-- これらは「別々のユーザー」として扱われる
'app_user'@'localhost'      -- ローカルからのみ接続可能
'app_user'@'192.168.1.100'  -- 特定IPからのみ
'app_user'@'192.168.1.%'    -- 192.168.1.x全般から
'app_user'@'%'              -- どこからでも

つまり、app_user というユーザー名が同じでも、接続元ホストが違えば別のユーザーとして扱われます。これがMySQL認証で多くの混乱を生む元となります。

エラーメッセージの読み解き方

Access denied for user 'app_user'@'192.168.1.100' (using password: YES)
要素意味
'app_user'接続を試みたユーザー名
'192.168.1.100'サーバーから見た接続元のIP/ホスト名
using password: YESパスワードを送信した
using password: NOパスワードを送信していない

特に重要: @ の後ろは、自分のマシン名ではなくMySQLサーバーから見た自分のアドレスです。NAT越しなら全く違うIPになります。


エラーの原因カテゴリ

カテゴリ頻度
パスワード関連入力ミス、リセット忘れ、特殊文字エスケープ最多
ホスト指定問題localhost vs %、IP違い、ホスト名解決失敗
ユーザー未作成該当ユーザーが存在しない
権限不足ユーザーは存在するが該当DBに権限なし
認証プラグインcaching_sha2_password と mysql_native_password の競合中(MySQL 8.0以降特に)
root特殊事情rootパスワード忘れ、auth_socket認証
設定問題skip-name-resolve、bind-address制限
Docker/クラウド固有コンテナ内外、AWS RDS設定

これらを順番に切り分けます。


【原因①】パスワードの入力ミス・特殊文字

最も多いケースです。基本ですが意外な落とし穴も。

よくあるタイプミス

  • スペース混入(前後・中間)
  • Caps Lock有効
  • 全角文字混入
  • 似た文字の混同(O/0l/1I/l
  • メモ帳からコピー時の改行コード・ゼロ幅スペース混入

コマンドラインでの特殊文字エスケープ

パスワードに$!"'等の記号が含まれる場合、シェルが解釈してしまう可能性:

# ❌ 失敗例($がシェルで解釈される)
mysql -u app -p$ecret!Pass

# ✅ シングルクォートで囲む
mysql -u app -p'$ecret!Pass'

# ✅ 対話的にプロンプトで入力(最も安全)
mysql -u app -p
# Enter password: ← 表示されない入力

Windows コマンドプロンプト

mysql -u app -p"$ecret!Pass"

-p の前後にスペースを入れない

# ❌ NG(パスワードがDB名と解釈される)
mysql -u app -p secretpass

# ✅ OK(スペースなし)
mysql -u app -psecretpass

# ✅ OK(プロンプトで入力)
mysql -u app -p

【原因②】ホスト指定の不一致(最頻出・要注意)

MySQL認証の特殊性で最も混乱を生む原因です。

現象

'app_user'@'localhost' で接続OKなのに、'app_user'@'127.0.0.1' で接続NG、というケース。これは:

  • 'app_user'@'localhost' ユーザーが作成されている
  • 'app_user'@'127.0.0.1' または 'app_user'@'%' は作成されていない

ためです。

localhost と 127.0.0.1 は別物

MySQLでは:

  • localhost: UNIXソケット接続(TCPを介さない)
  • 127.0.0.1: TCP/IP経由のループバック接続

接続プロトコルが違うため、別のユーザーエントリが必要です。

接続時にどちらが使われるか確認

# UNIX socket強制
mysql --protocol=socket -u app -p

# TCP/IP強制
mysql --protocol=tcp -h 127.0.0.1 -u app -p

自分が「どこから接続している」と見えるか確認

サーバー上で接続中のセッション一覧を見ると分かります:

SELECT host FROM information_schema.processlist WHERE user = CURRENT_USER();
-- または
SELECT CURRENT_USER();
-- 結果例: 'app_user'@'192.168.1.100'

ユーザー一覧でホスト指定を確認

SELECT user, host FROM mysql.user WHERE user = 'app_user';

出力例:

+----------+-------------+
| user     | host        |
+----------+-------------+
| app_user | localhost   |
| app_user | %           |
+----------+-------------+

localhost% は別エントリで、それぞれパスワードや権限が独立しています。

対処:必要なホスト指定でユーザーを作成

-- 192.168.1.100からのみ接続を許可
CREATE USER 'app_user'@'192.168.1.100' IDENTIFIED BY 'password';
GRANT ALL ON appdb.* TO 'app_user'@'192.168.1.100';

-- 192.168.1.x全般から
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'password';

-- どこからでも(開発環境のみ推奨)
CREATE USER 'app_user'@'%' IDENTIFIED BY 'password';

FLUSH PRIVILEGES;

⚠️ '%'は世界中からの接続を意味するセキュリティリスクがあります。本番では具体的IP範囲に限定推奨。

skip-name-resolve の影響

my.cnfに以下が設定されているとホスト名→IP変換が行われません:

[mysqld]
skip-name-resolve

この場合、'user'@'webserver'のようなホスト名指定ユーザーは認証失敗します。IPアドレスで指定しましょう。

-- ホスト名指定(skip-name-resolve環境では動かない)
'app_user'@'webserver.example.com'

-- IPで指定(推奨)
'app_user'@'192.168.1.100'

設定確認:

SHOW VARIABLES LIKE 'skip_name_resolve';

【原因③】認証プラグインの不一致(MySQL 8.0以降の重要原因)

MySQL 8.0からデフォルト認証プラグインがcaching_sha2_passwordに変更され、古いクライアント・ドライバとの互換性問題が頻発します。

認証プラグインの確認

SELECT user, host, plugin FROM mysql.user;

主な値:

プラグイン説明
caching_sha2_passwordMySQL 8.0デフォルト。高セキュリティだが古いクライアント非対応
mysql_native_password5.7以前のデフォルト。広く互換性あり
auth_socketUNIXソケット経由でOSユーザーと連携(Linux root等)
sha256_password古い強化認証(非推奨)

MySQL 8.0でのよくある現象

  • Java JDBC(古いConnector/J)で接続失敗
  • PHP(mysqlnd未対応版)で接続失敗
  • Workbench接続で Authentication plugin caching_sha2_password cannot be loaded

対処1:ユーザーの認証プラグインを変更

特定ユーザーだけを互換性プラグインに:

ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

対処2:MySQLサーバーのデフォルト変更

/etc/mysql/my.cnf または mysqld.cnf に追加:

[mysqld]
default-authentication-plugin=mysql_native_password

設定後にMySQLサーバー再起動。新規作成されるユーザーはこのプラグインで作られます。

⚠️ MySQL 8.4以降ではmysql_native_passwordがデフォルトで無効化されています。明示的に有効化が必要:

[mysqld]
mysql_native_password=ON

対処3:クライアントを更新

根本的にはクライアント側のドライバを新しくするのがベスト:

  • JDBC: mysql-connector-j 8.0.x以降
  • PHP: mysqlnd(PHP 5.4+で標準)を使用
  • Python: mysql-connector-python 8.0.x以降、または PyMySQL

auth_socket の場合(特殊)

UbuntuのMySQL初期インストール時、rootauth_socketプラグインで設定されます。これは「OS上で root ユーザーが実行した場合のみ」認証が通る仕組みで、パスワード認証ではありません。

# OS上のrootから(成功)
sudo mysql

# 一般ユーザーから(失敗)
mysql -u root -p  # → ERROR 1045

対処:

# sudo付きで接続
sudo mysql

# プラグイン変更
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpassword';
FLUSH PRIVILEGES;
EXIT

これで通常のパスワード認証も使えるようになります。


【原因④】rootパスワードを忘れた場合

最後の手段としての、rootパスワードリセット手順です。

Linux(systemd環境)

手順1:MySQLを安全モードで起動

# MySQLを停止
sudo systemctl stop mysql

# 認証なしで起動
sudo mysqld_safe --skip-grant-tables --skip-networking &

# またはsystemd経由
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mysql

手順2:パスワード変更

# パスワードなしで接続
mysql -u root
-- 認証情報をリロード(grant tablesをロード)
FLUSH PRIVILEGES;

-- パスワード変更
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';

EXIT;

手順3:通常モードで再起動

sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl restart mysql

これでmysql -u root -pで新パスワード接続できます。

Windows

REM MySQL停止
net stop MySQL80

REM init.txtを作成
echo ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password'; > C:\temp\init.txt

REM 初期化ファイル指定で起動
mysqld --init-file=C:\temp\init.txt --console

REM 別ウィンドウから接続確認
mysql -u root -p

REM 通常モードに戻す(Ctrl+C で初期化モード停止後)
net start MySQL80

Docker環境

Docker環境では別アプローチ:

# 1. 環境変数で初期化されたコンテナを削除
docker stop mysql-container
docker rm mysql-container

# 2. 新しい環境変数で再作成
docker run -d --name mysql-container \
    -e MYSQL_ROOT_PASSWORD=new_password \
    -p 3306:3306 \
    -v mysql_data:/var/lib/mysql \
    mysql:8.0

⚠️ 既存ボリュームの場合はパスワード初期化されません。ボリューム削除 or --skip-grant-tables 経由のリセットが必要です。


【原因⑤】ユーザーが存在しない・権限不足

シンプルですが多いケース。

ユーザーの存在確認

SELECT user, host FROM mysql.user WHERE user = 'app_user';

何も返ってこなければユーザー未作成です。

権限の確認

SHOW GRANTS FOR 'app_user'@'localhost';

出力例:

GRANT USAGE ON *.* TO `app_user`@`localhost`

USAGEだけだとログインはできるがDB操作不可USAGEは単純な接続権限です。

権限付与

-- 特定DBへの全権限
GRANT ALL PRIVILEGES ON appdb.* TO 'app_user'@'localhost';

-- 読み取り専用
GRANT SELECT ON appdb.* TO 'app_user'@'localhost';

-- 複数操作
GRANT SELECT, INSERT, UPDATE, DELETE ON appdb.* TO 'app_user'@'localhost';

-- 全DBへのスーパーユーザー権限(要注意)
GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'localhost' WITH GRANT OPTION;

-- 反映
FLUSH PRIVILEGES;

「Access denied for user (using password: NO)」の場合

パスワードを送信していない状態です。原因:

  • パスワードオプション -p を付け忘れた
  • スクリプトでパスワード変数が空になっていた
# ❌
mysql -u app

# ✅
mysql -u app -p

匿名ユーザーの罠

MySQLには歴史的経緯で''@'localhost'空ユーザー名)が存在することがあります。これがあると、ユーザー名指定なしでも接続できてしまい、セキュリティリスクになります。

SELECT user, host FROM mysql.user WHERE user = '';

該当があれば削除:

DROP USER ''@'localhost';
DROP USER ''@'%';
FLUSH PRIVILEGES;

【原因⑥】bind-address による接続制限

サーバー側でリスナーのバインドアドレスを制限している場合、リモート接続が拒否されます。

現状確認

SHOW VARIABLES LIKE 'bind_address';
動作
127.0.0.1localhostのみ受け付け(デフォルト:MySQL 8.0以降は変更されたバージョンあり)
0.0.0.0すべてのインターフェース
::IPv6含む全インターフェース
特定IPそのIPのみ

127.0.0.1 の場合、リモートからは ORA-1045 ではなく接続拒否

リモートから接続を試みると、エラー1045ではなく 2003 (HY000): Can't connect to MySQL server が出ることが多いですが、ファイアウォール構成によっては1045として返ることもあります。

対処:bind-address 変更

/etc/mysql/mysql.conf.d/mysqld.cnf:

[mysqld]
bind-address = 0.0.0.0

MySQL再起動:

sudo systemctl restart mysql

⚠️ 外部公開する場合は、ファイアウォールとMySQLユーザーのホスト指定の両方で適切な制限を必ず設定してください。


Docker環境でのERROR 1045

Docker MySQL は特殊事情があります。

よくあるシナリオ

# コンテナ起動
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=mypass -p 3306:3306 mysql:8.0

# ホストから接続
mysql -h 127.0.0.1 -u root -p
# ERROR 1045 (28000): Access denied for user 'root'@'172.17.0.1'

原因: Docker MySQLのrootデフォルトで'root'@'localhost'のみ作成されており、ホストからの接続(コンテナから見ると別IP)は拒否されます。

対処1:環境変数でリモート root を有効化

docker run -d --name mysql \
    -e MYSQL_ROOT_PASSWORD=mypass \
    -e MYSQL_ROOT_HOST=% \
    -p 3306:3306 \
    mysql:8.0

MYSQL_ROOT_HOST=%で全ホストからroot接続可能になります。

対処2:別ユーザーを作成

docker run -d --name mysql \
    -e MYSQL_ROOT_PASSWORD=mypass \
    -e MYSQL_USER=appuser \
    -e MYSQL_PASSWORD=apppass \
    -e MYSQL_DATABASE=appdb \
    -p 3306:3306 \
    mysql:8.0

MYSQL_USERで作成されるユーザーは'appuser'@'%'としてアクセス可能です。

対処3:コンテナ内部に入って手動で設定

docker exec -it mysql mysql -u root -p

# コンテナ内で
mysql> CREATE USER 'app'@'%' IDENTIFIED BY 'apppass';
mysql> GRANT ALL ON *.* TO 'app'@'%';
mysql> FLUSH PRIVILEGES;

docker-compose 例

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_ROOT_HOST: '%'         # ← リモートrootアクセス
      MYSQL_DATABASE: appdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

クラウドDB(AWS RDS、Aurora、Cloud SQL等)

クラウドマネージドDBでも頻発するエラーです。

AWS RDS for MySQL / Aurora

よくある原因

  • マスターユーザーのパスワード忘れ → RDSコンソールで変更
  • セキュリティグループでクライアントIPからの接続が許可されていない
  • VPC外からの接続でパブリックアクセスが無効化されている

対処:マスターパスワード変更

  1. AWS Console → RDS → 該当インスタンスを選択
  2. 「変更」→ 「新しいマスターパスワード」入力
  3. 反映に1〜2分かかる

接続元 IP 確認

curl ifconfig.me   # 自分のグローバルIP

セキュリティグループのインバウンドルールに自分のIP + 3306ポートが許可されている確認。

Google Cloud SQL

# Cloud SQL Authプロキシ経由が推奨
./cloud_sql_proxy -instances=PROJECT:REGION:INSTANCE=tcp:3306
mysql -u root -p -h 127.0.0.1

直接接続の場合は、Cloud SQL の「Authorized networks」設定でクライアントIPを追加。

Azure Database for MySQL

Azure Portal → MySQL サーバー → 「接続のセキュリティ」 → ファイアウォール規則でクライアントIPを許可。

ユーザー名フォーマットの違い

クラウドサービスによって特殊なユーザー名形式が必要なことがあります:

  • Azure Database for MySQL: username@servername
  • AWS RDS Proxy経由: IAMトークン認証の場合は特殊

各サービスの公式ドキュメントを確認してください。


プログラム言語別 ERROR 1045 対処

PHP(PDO・mysqli)

<?php
try {
    $pdo = new PDO(
        'mysql:host=localhost;dbname=appdb;charset=utf8mb4',
        'app_user',
        'password'
    );
} catch (PDOException $e) {
    if ($e->getCode() == 1045) {
        echo "認証エラー: ユーザー名・パスワード・ホスト指定を確認\n";
    }
    throw $e;
}

PHP(caching_sha2_passwordエラー)

PHP Fatal error: Uncaught PDOException: SQLSTATE[HY000] [2054] 
    The server requested authentication method unknown to the client

このエラーは ERROR 1045 とセットで出ます。対処:

ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

または PHP のmysqlndモジュールを新しくする。

Python(PyMySQL / mysql-connector-python)

import pymysql

try:
    conn = pymysql.connect(
        host='localhost',
        user='app_user',
        password='password',
        database='appdb'
    )
except pymysql.err.OperationalError as e:
    if e.args[0] == 1045:
        print("ERROR 1045: 認証失敗")
        print("- パスワード確認")
        print("- 'user'@'host' の組み合わせ確認")
        print(f"- 接続元IP: {e}")

Java(JDBC)

String url = "jdbc:mysql://localhost:3306/appdb?useSSL=false";
try {
    Connection conn = DriverManager.getConnection(url, "app_user", "password");
} catch (SQLException e) {
    if (e.getErrorCode() == 1045) {
        System.err.println("ERROR 1045: 認証失敗");
        System.err.println("確認事項:");
        System.err.println("- パスワード");
        System.err.println("- ユーザーのホスト指定");
        System.err.println("- mysql_native_password vs caching_sha2_password");
    }
}

JDBC ドライバの選択:

  • MySQL 5.7まで: mysql-connector-java 5.1.x または 8.x
  • MySQL 8.0以降: mysql-connector-j 8.0.x(旧名 mysql-connector-java は廃止)

Node.js(mysql2)

const mysql = require('mysql2/promise');

try {
    const conn = await mysql.createConnection({
        host: 'localhost',
        user: 'app_user',
        password: 'password',
        database: 'appdb'
    });
} catch (err) {
    if (err.errno === 1045) {
        console.error('ERROR 1045 - 認証失敗');
        console.error('原因候補:', err.message);
    }
}

mysql2caching_sha2_passwordに対応していますが、古いmysqlパッケージは未対応。マイグレーションが必要です。

.NET(MySql.Data)

using MySql.Data.MySqlClient;

string connStr = "server=localhost;user=app;password=secret;database=appdb;";
try {
    using var conn = new MySqlConnection(connStr);
    conn.Open();
} catch (MySqlException ex) when (ex.Number == 1045) {
    Console.WriteLine("認証エラー: ユーザー/パスワード/ホスト確認");
}

関連エラーと違い

ERROR 1044 (42000): Access denied for user to database

接続認証は成功したが、特定データベースへの権限がない場合。

GRANT ALL ON dbname.* TO 'user'@'host';
FLUSH PRIVILEGES;

ERROR 1142: command denied to user

特定操作の権限がない。例: SELECT権限はあるがDELETE権限がない。

GRANT DELETE ON dbname.tablename TO 'user'@'host';

ERROR 2003: Can’t connect to MySQL server

そもそもサーバーに到達できない。1045とは別物(ネットワーク、bind-address、ポート問題)。

ERROR 2059: Authentication plugin ‘caching_sha2_password’ cannot be loaded

クライアント側がcaching_sha2_passwordプラグインを認識できない。対処:

  • クライアントドライバ更新
  • またはサーバー側でmysql_native_passwordに変更

ERROR 1396: Operation CREATE USER failed

既に同じユーザーが存在する。

-- 存在確認
SELECT user, host FROM mysql.user WHERE user = 'app';

-- 削除してから再作成
DROP USER 'app'@'%';
CREATE USER 'app'@'%' IDENTIFIED BY 'pass';

セキュリティ・運用ベストプラクティス

ERROR 1045 を回避しつつ、安全な運用を実現するための指針です。

1. root はリモートから繋がない

-- root のホストは localhost のみに限定
SELECT user, host FROM mysql.user WHERE user = 'root';

-- リモート可能な root エントリは削除
DROP USER 'root'@'%';

2. アプリケーションごとに専用ユーザー

-- 各アプリ用ユーザーを最小権限で作成
CREATE USER 'webapp'@'10.0.1.%' IDENTIFIED BY 'WebAppP@ss2026';
GRANT SELECT, INSERT, UPDATE, DELETE ON webdb.* TO 'webapp'@'10.0.1.%';

CREATE USER 'batch'@'10.0.2.%' IDENTIFIED BY 'BatchP@ss2026';
GRANT SELECT ON webdb.* TO 'batch'@'10.0.2.%';

3. パスワードの定期更新

-- パスワード有効期限を90日に
ALTER USER 'webapp'@'10.0.1.%' PASSWORD EXPIRE INTERVAL 90 DAY;

4. 接続元IPの範囲を厳格化

-- ❌ 開発のみ
'app'@'%'

-- ✅ 本番(社内ネットワークから限定)
'app'@'10.0.0.0/255.0.0.0'

ただしMySQLのhostはCIDR非対応で、10.%等のワイルドカードで指定します。

5. 匿名ユーザー・テストDBの削除

DELETE FROM mysql.user WHERE user = '';
DROP DATABASE IF EXISTS test;
FLUSH PRIVILEGES;

mysql_secure_installationコマンドで自動的に行えます。

6. パスワードポリシーの強化

SET GLOBAL validate_password.policy = STRONG;
SET GLOBAL validate_password.length = 12;

7. 失敗ログイン試行の監視

general_logを一時的に有効化して、認証失敗を観測:

SET GLOBAL general_log = 'ON';
SET GLOBAL log_output = 'TABLE';

-- 失敗ログの確認
SELECT * FROM mysql.general_log WHERE argument LIKE '%Access denied%';

トラブルシューティング・チェックリスト

ERROR 1045 が出た時に上から順にチェック:

  1. エラーメッセージから'user'@'host'を確認
  2. (using password: YES/NO)を確認
  3. MySQL サーバー上でSELECT user, host FROM mysql.user実行
  4. 該当ユーザーが存在するか、ホスト指定が一致するか確認
  5. パスワード再設定で接続テスト
  6. MySQL 8.0以降なら認証プラグインを確認
  7. skip-name-resolvebind-address設定確認
  8. Docker環境ならMYSQL_ROOT_HOSTを確認
  9. クラウドDBならセキュリティグループ・ファイアウォール確認
  10. クライアントドライバが新しい認証方式に対応しているか確認

よくある質問(FAQ)

Q1. ローカルでは繋がるのにアプリから接続できません

ユーザーのホスト指定が問題の可能性が高いです。アプリサーバーから見たMySQLサーバー上での「アプリのIPアドレス」を確認:

-- 接続失敗時のエラーメッセージから 'user'@'host' を確認
-- そのホストでユーザーが登録されているか確認
SELECT user, host FROM mysql.user WHERE user = 'app';

Q2. (using password: NO) と表示されます

パスワードが空文字、または送信されていません:

# パスワード忘れ
mysql -u app  # ❌

# パスワード指定
mysql -u app -p  # ✅

Q3. MySQL 8 にアップグレード後、PHPアプリが繋がらなくなりました

caching_sha2_passwordへのプラグイン変更が原因の可能性大。mysql_native_passwordに変更:

ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'password';

長期的にはPHPのmysqlndモジュール更新を推奨。

Q4. root のパスワードを変更したらどこからも繋がらなくなりました

ALTER USER でホスト指定をミスした可能性:

-- 全rootエントリ確認
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';

'root'@'localhost'以外のエントリにパスワード設定したかも。本記事のrootパスワードリセット手順で復旧。

Q5. ユーザーが存在するのに接続できません

主な原因:

  • ホスト指定('user'@'localhost'vs'user'@'%')が違う
  • パスワードが間違っている
  • 認証プラグインがクライアント未対応
SELECT user, host, plugin FROM mysql.user WHERE user = 'app';

の結果で確認してください。

Q6. SSL関連でエラーが出ます

MySQL 8.0以降、デフォルトでSSL要求があります:

# SSLを無効化(開発のみ)
mysql -u app -p --ssl-mode=DISABLED

# クライアント側で対応

JDBCの場合:

jdbc:mysql://host:3306/db?useSSL=false&allowPublicKeyRetrieval=true

Q7. Docker でMySQLに繋がりません

最頻出原因は 'root'@'localhost' のみ作成され、ホスト側から繋ぐ際の 'root'@'172.17.0.1'等の組み合わせがないこと。本記事のDocker環境セクションを参照。

Q8. AWS RDS に接続できなくなりました

確認順:

  1. RDSインスタンスは起動しているか(Available状態)
  2. セキュリティグループに自分のIPが許可されているか
  3. パブリックアクセスが「あり」になっているか(VPC外接続の場合)
  4. マスターパスワードを正しく覚えているか
  5. エンドポイント(URL)が正しいか

Q9. mysql_native_password が使えないバージョンがあるの?

MySQL 8.4以降はmysql_native_passwordがデフォルトで無効化されています:

# my.cnf に追加で復活

[mysqld]

mysql_native_password=ON

ただし将来的には完全削除される予定なので、クライアント更新が本筋です。

Q10. /tmp/mysql.sock で繋がりません

ソケットファイルパスが違う可能性:

SHOW VARIABLES LIKE 'socket';

クライアント側でも合わせる:

mysql -u root -p --socket=/var/run/mysqld/mysqld.sock

my.cnfに永続化:

[client]
socket=/var/run/mysqld/mysqld.sock

Q11. アプリのパスワード変更後、しばらくして接続できなくなります

接続プールに古い認証情報が残っている可能性。アプリ再起動で解決します。

Q12. パスワードを忘れたが MySQL の停止ができません

本番稼働中で停止できない場合の選択肢:

  • 別ユーザーで SUPER 権限を持つアカウントを使う
  • レプリカDBで作業し、後でフェイルオーバー
  • どうしても無理ならメンテナンス時間を確保して手順実行

クラウドマネージドDB(RDS等)ならコンソールから即時変更可能です。


参考リンク・関連資料

MySQL公式ドキュメント

MariaDB

クライアントドライバ

Docker / クラウド

関連エラー記事(本サイト)


まとめ

MySQL ERROR 1045 は、シンプルなメッセージとは裏腹に10以上の原因があります。要点を再整理します。

  • MySQL認証の鍵: 「ユーザー名+ホスト指定」のペアで管理(他DBと違う)
  • エラーメッセージから情報を読む: 'user'@'host' (using password: YES/NO) から原因を絞り込む
  • 最頻出はホスト指定不一致: 'user'@'localhost''user'@'%'は別ユーザー
  • MySQL 8.0以降: caching_sha2_passwordと古いクライアントの互換性問題が頻発
  • rootパスワード忘れ: --skip-grant-tablesモードでリセット可能
  • Docker: MYSQL_ROOT_HOST=% または別ユーザー作成
  • クラウド: セキュリティグループ・ファイアウォール・マスターユーザー設定
  • セキュリティ: 最小権限の原則、ホスト範囲限定、パスワードポリシー強化

これらの知識は、Webアプリ開発・データベース管理・本番運用・トラブル対応など、MySQL を扱うあらゆる場面で必須です。本記事をブックマークしておけば、ERROR 1045 に遭遇した時の対応が大幅に効率化されます。


本記事は2026年6月時点の情報をもとに、MySQL 5.7 / 8.0 / 8.4 および MariaDB 10.x / 11.x での動作確認・公式ドキュメントに基づき作成しています。バージョンによってデフォルト動作が異なる場合があるため、最新の情報はMySQL公式ドキュメントもあわせてご確認ください。