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:3306or 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.
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(, ),
=> (, ),
=> (, ),
=> (, ),
=> (, ),
],
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:
- Artisan boots the Laravel application.
- Laravel loads its database configuration, including values from the environment.
- Laravel asks PDO to create a MySQL connection.
- Because the host is
localhost, the MySQL driver may try to use a local Unix socket instead of TCP. - PDO looks for the socket file at its configured or default path.
- 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 --forceagainst a production database. - Seed data: running
php artisan db:seedto 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.
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
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.
Comparisons
| Connection choice | Example | Best use | Common concern |
|---|---|---|---|
| Unix socket | DB_SOCKET=/path/to/mysql.sock | A documented local MySQL socket | The path must exist on that exact server. |
| TCP using loopback | DB_HOST=127.0.0.1 | MySQL running locally, but accessed over the network stack | Requires MySQL to listen on TCP. |
| TCP using a provider host | DB_HOST=db.provider.example | Managed or remote databases | Use the provider's required host, port, and network settings. |
localhost | DB_HOST=localhost | Only when the environment is known to support it | May select a Unix socket rather than TCP. |
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.
localhostmay use a socket;127.0.0.1uses 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:
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.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.