Question

Fix PDOException SQLSTATE[HY000] [2002] in Laravel PHP

phpmysqllaraveldatabasepdo

Question

A basic Laravel site has been deployed to fortrabbit. When connecting through SSH and running Artisan commands such as the following, Laravel throws a PDO exception:

php artisan migrate
php artisan db:seed
[PDOException]
SQLSTATE[HY000] [2002] No such file or directory

The database tables appear to exist, suggesting that a migration worked previously. Why does this error occur when running Artisan commands, and how can the database connection be configured correctly?

Short Answer

This page explains what PDO error SQLSTATE[HY000] [2002] No such file or directory usually means in a Laravel application. You will learn the difference between a MySQL Unix socket connection and a TCP network connection, how Laravel reads database settings from environment variables, and how cached configuration can make a correct .env change appear ineffective.

Concept

PDO is PHP's database-access layer. Laravel uses PDO behind its database configuration, migrations, seeders, and Eloquent models.

The error code SQLSTATE[HY000] [2002] means PHP could not connect to the MySQL server. Although the message says No such file or directory, it often does not mean that your migration files or database tables are missing.

On Unix-like systems, MySQL can be reached in two common ways:

  • Unix socket: a special local file used for communication between processes on the same server.
  • TCP connection: a network-style connection using a hostname and port, such as 127.0.0.1:3306 or a host supplied by a managed hosting provider.

A frequent cause is using localhost as DB_HOST. Many MySQL clients interpret localhost as “use the local Unix socket.” If that socket file does not exist at the expected path, PDO reports error 2002 with this message.

Managed platforms commonly provide a specific database hostname, port, database name, username, and password. Use those exact credentials rather than assuming that the database is local. This matters especially for SSH commands: php artisan migrate runs on the server, and it must be able to load the same correct environment configuration as the deployed application.

Mental Model

Think of the database as an office you need to contact.

  • A Unix socket is like an internal hallway between two rooms in the same building. It only works if the office is actually in that building and the hallway is at the expected door.
  • A TCP host and port is like calling the office using its phone number. It works even when the office is in another building.

Using localhost can tell PHP to look for the internal hallway. If your hosted database is elsewhere, or the hallway path is different, PHP cannot find it and reports “No such file or directory.” The database itself may still be healthy and may still contain all of your tables.

Take Quiz

Syntax and Examples

Laravel normally reads database values from .env and passes them to config/database.php.

A typical MySQL configuration in .env looks like this:

DB_CONNECTION=mysql
DB_HOST=db.example-host.com
DB_PORT=3306
DB_DATABASE=app_database
DB_USERNAME=app_user
DB_PASSWORD=replace-with-real-password

Use the values shown in your hosting provider's database dashboard or connection details.

If you are intentionally connecting to a MySQL server on the same machine over TCP, prefer 127.0.0.1 over localhost:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=app_database
DB_USERNAME=app_user
DB_PASSWORD=secret

127.0.0.1 explicitly requests a TCP connection. In contrast, localhost may request a Unix socket connection.

Laravel's default MySQL configuration is similar to this:

'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'laravel'),
    'username' => env('DB_USERNAME', 'root'),
    'password' => env('DB_PASSWORD', ''),
    'unix_socket' => env('DB_SOCKET', ''),
],

Set DB_SOCKET only when your database provider explicitly gives you a socket path. Do not invent a socket path or use one copied from a different server.

Step by Step Execution

Consider this environment file:

DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=shop
DB_USERNAME=shop_user
DB_PASSWORD=secret

When you run:

php artisan migrate

Laravel proceeds roughly as follows:

  1. Artisan boots the Laravel application.
  2. Laravel loads its database configuration, including values from the environment.
  3. Laravel asks PDO to create a MySQL connection.
  4. Because the host is localhost, the MySQL driver may try to use a local Unix socket instead of TCP.
  5. PDO looks for the socket file at its configured or default path.
  6. If no socket exists there, PDO cannot open it and throws:
SQLSTATE[HY000] [2002] No such file or directory

If the provider instead supplies a remote host, change the configuration to that host:

DB_HOST=mysql.internal.provider.example
DB_PORT=3306

Then clear Laravel's cached configuration before testing again:

php artisan config:clear
php artisan cache:clear
php artisan migrate:status

migrate:status is useful because it tests the connection and lists migration state without applying new migrations.

Real World Use Cases

Database connection settings are used in many everyday tasks:

  • Deployments: running php artisan migrate --force against a production database.
  • Seed data: running php artisan db:seed to create initial roles, categories, or test records.
  • Queue workers: workers must connect to the database when using the database queue driver.
  • Scheduled commands: cron-triggered Artisan commands need the same database configuration as web requests.
  • Local development: a local MySQL installation may use a socket, while Docker and cloud databases usually use TCP.
  • Multiple environments: local, staging, and production commonly have different database hosts and credentials.

The key practice is to treat connection settings as environment-specific configuration, not as hard-coded application logic.

Take Quiz

Real Codebase Usage

In real Laravel projects, developers usually keep database credentials outside source control and inject them through platform environment variables or a server-side .env file.

Use provider-provided connection values

Set DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, and DB_PASSWORD to the exact values provided by the host. A managed database may not be reachable through localhost, even when the application itself runs on that platform.

Clear configuration after changes

Laravel can cache configuration for performance. If configuration was cached before an environment variable changed, Artisan may continue using old values.

php artisan config:clear
php artisan cache:clear
php artisan config:cache

Run config:cache only when your deployment process expects cached configuration. Do not run it before the correct environment values are available.

Test safely before migrating

Use a non-destructive connection check first:

php artisan migrate:status

Then run production migrations deliberately:

php artisan migrate --force

The --force option is required by Laravel when running migrations in the production environment.

Keep secrets out of code

Do not commit a production .env file or credentials to Git. Commit .env.example with placeholder values instead:

DB_CONNECTION=mysql
DB_HOST=
DB_PORT=3306
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=

Common Mistakes

Assuming “No such file or directory” means tables are missing

This error happens while PDO is trying to connect. It normally occurs before Laravel can inspect tables or execute a migration.

Avoid it: verify the connection host, port, username, password, and socket settings first.

Using localhost for a remote managed database

# Often wrong on managed hosting
DB_HOST=localhost

This can trigger a socket connection attempt.

Avoid it: use the database hostname shown by your host. If the database is truly local but you want TCP, use:

DB_HOST=127.0.0.1

Changing .env but leaving configuration cached

You edit .env, run Artisan again, and see the same error because Laravel is still using cached configuration.

Avoid it: run:

php artisan config:clear

Then retry php artisan migrate:status.

Guessing a socket path

# Broken unless this exact socket exists on this server
DB_SOCKET=/var/run/mysqld/mysqld.sock

Socket paths differ between operating systems, MySQL installations, containers, and hosting platforms.

Avoid it: omit DB_SOCKET unless your provider documents the exact path.

Hard-coding credentials in config/database.php

'password' => 'production-secret',

This risks exposing secrets in Git and makes environment changes difficult.

Avoid it: use env() values through Laravel's standard configuration and set secrets in environment configuration.

Running migrations before checking the target database

A wrong host can point to an unexpected database; a wrong environment may be dangerous.

Avoid it: confirm the environment and run php artisan migrate:status before applying migrations.

Comparisons

Connection choiceExampleBest useCommon concern
Unix socketDB_SOCKET=/path/to/mysql.sockA documented local MySQL socketThe path must exist on that exact server.
TCP using loopbackDB_HOST=127.0.0.1MySQL running locally, but accessed over the network stackRequires MySQL to listen on TCP.
TCP using a provider hostDB_HOST=db.provider.exampleManaged or remote databasesUse the provider's required host, port, and network settings.
localhostDB_HOST=localhostOnly when the environment is known to support itMay select a Unix socket rather than TCP.
Laravel commandWhat it doesChanges data?
php artisan migrate:statusChecks the database and shows migration stateNo
php artisan migrateApplies outstanding migrationsYes
php artisan db:seedRuns database seedersUsually yes
php artisan config:clearRemoves Laravel's configuration cacheNo database changes
Take Quiz

Cheat Sheet

# Typical remote or managed MySQL connection
DB_CONNECTION=mysql
DB_HOST=provider-supplied-host
DB_PORT=3306
DB_DATABASE=provider-supplied-database
DB_USERNAME=provider-supplied-user
DB_PASSWORD=provider-supplied-password
# Local MySQL over TCP
DB_HOST=127.0.0.1
DB_PORT=3306
# Use only when the host documents a socket path
DB_SOCKET=/exact/path/to/mysql.sock
# Remove stale Laravel configuration
php artisan config:clear

# Test connection and inspect migration state
php artisan migrate:status

# Apply production migrations
php artisan migrate --force
  • Error SQLSTATE[HY000] [2002] is a connection failure.
  • “No such file or directory” commonly refers to a missing or inaccessible Unix socket file.
  • localhost may use a socket; 127.0.0.1 uses TCP.
  • Use the host's exact database credentials.
  • After changing environment settings, clear cached configuration.

FAQ

What does PDOException SQLSTATE[HY000] [2002] mean in Laravel?

It means PDO could not establish a MySQL connection. With the message “No such file or directory,” the attempted Unix socket file is often missing or at a different path.

Why do my tables exist if php artisan migrate cannot connect now?

The tables may have been created during an earlier successful deployment, with different environment variables, or by a different connection path. Their existence does not prove the current Artisan process has correct credentials.

Should I use localhost or 127.0.0.1 for DB_HOST?

Use the hostname supplied by your database provider for a managed database. For a local database where you specifically want TCP, use 127.0.0.1. localhost may use a Unix socket.

When should I set DB_SOCKET in Laravel?

Only set it when the database server or hosting provider explicitly provides a socket path. Most remote managed database connections do not need it.

Why is Laravel ignoring my .env database changes?

Laravel may have cached its configuration. Run php artisan config:clear, then test again. Also confirm that the command runs in the correct project directory and environment.

How can I test a Laravel database connection without running migrations?

Run:

php artisan migrate:status

It needs a working database connection but does not apply migrations.

Is this error caused by a missing Laravel migration file?

Usually no. The error is raised before Laravel can run or locate migrations because it cannot connect to MySQL.

Take Quiz

Mini Project

Description

Create a small Laravel database-connection checklist command. It displays the non-secret connection settings currently loaded by Laravel and verifies the connection before a migration is attempted. This demonstrates environment configuration, safe diagnostics, and Laravel's database facade.

Goal

Build an Artisan command that reports the active database connection settings and confirms whether Laravel can reach MySQL.

Requirements

Show the default connection name and the configured host, port, and database name without printing the password. Attempt a simple database connection test. Print a success message when the connection works. Print a readable error message and a non-zero exit code when the connection fails. Run the command before using migration commands during deployment.

Take Quiz

Keep learning

Related questions

View more