Laravel "SQLSTATE[HY000] [1045] Access denied for user" in CI
MySQL rejected the login because the user or password Laravel sent does not match the account the CI MySQL service was started with. The database is reachable; the credentials are wrong. Align DB_USERNAME and DB_PASSWORD with the service definition.
What this error means
Migrations or tests fail with "SQLSTATE[HY000] [1045] Access denied for user 'root'@... (using password: YES/NO)". The MySQL service is up but Laravel authenticates with the wrong credentials.
Illuminate\Database\QueryException
SQLSTATE[HY000] [1045] Access denied for user 'root'@'172.17.0.1'
(using password: NO)Common causes
DB env does not match the MySQL service
The services.mysql block sets a password (or a non-root user) that DB_USERNAME/DB_PASSWORD in Laravel does not match, so the login fails.
Password sent as empty when the service requires one
"using password: NO" means Laravel sent no password to a server that requires one, usually because DB_PASSWORD was not set in the env.
How to fix it
Match Laravel DB env to the service credentials
- Read the MYSQL_* values from the MySQL service block.
- Set DB_USERNAME and DB_PASSWORD in the job env to match exactly.
- Point DB_HOST at 127.0.0.1 and the mapped port.
services:
mysql:
image: mysql:8.0
env:
MYSQL_DATABASE: testing
MYSQL_ROOT_PASSWORD: password
ports: ['3306:3306']
env:
DB_HOST: 127.0.0.1
DB_USERNAME: root
DB_PASSWORD: passwordUse a dedicated user with a password
If you set MYSQL_USER/MYSQL_PASSWORD, use those in Laravel instead of root so credentials match a real account.
env:
DB_USERNAME: laravel
DB_PASSWORD: laravelHow to prevent it
- Keep DB_USERNAME/DB_PASSWORD in sync with the MySQL service env.
- Always set DB_PASSWORD explicitly, even for root.
- Wait for the DB service to be healthy before migrating.