Resolve the Laravel `SQLSTATE[42S02]` error during `artisan migrate` on Ubuntu 20.04 LTS. This guide covers database connection, permissions, caching, and Docker-related fixes.
This troubleshooting guide addresses a common Laravel error encountered when attempting to run database migrations, specifically "SQLSTATE[42S02]: Base table or view not found". This error typically indicates that Laravel cannot locate or access the expected database or a specific table within it, preventing successful schema evolution. It's a critical issue that halts development and deployment processes, often pointing to misconfigurations in database connectivity or permissions.
Symptom & Error Signature
When you execute the php artisan migrate command from your Laravel project's root directory, instead of a successful migration message, you will observe an error similar to the following in your terminal:
IlluminateDatabaseQueryException
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'your_database.migrations' doesn't exist (SQL: select migration from migrations order by batch asc, migration asc)
at vendor/laravel/framework/src/Illuminate/Database/Connection.php:712 708| // If an exception occurs when attempting to run a query, we'll format the error 709| // message to include the bindings with the query, which will make debugging 710| // the data a lot easier if these errors tend to pop up a lot. 711| catch (Exception $e) { 712| throw new QueryException( 713| $query, $this->prepareBindings($bindings), $e 714| ); 715| } 716|
Exception trace:
1 PDOException::("SQLSTATE[42S02]: Base table or view not found: 1146 Table 'your_database.migrations' doesn't exist") vendor/laravel/framework/src/Illuminate/Database/Connection.php:547
2 PDOStatement::execute()
vendor/laravel/framework/src/Illuminate/Database/Connection.php:547
`
The key parts of the error are SQLSTATE[42S02] and "Base table or view not found", often specifically mentioning the migrations table, or another table if you're running specific migrations on an existing, but possibly incomplete, database.
Root Cause Analysis
The SQLSTATE[42S02] error during artisan migrate fundamentally means Laravel couldn't find a table it expected to interact with. This can stem from several underlying issues:
- Incorrect Database Configuration: The most frequent cause. The
.envfile contains incorrect credentials (DBHOST,DBPORT,DBDATABASE,DBUSERNAME,DB_PASSWORD), leading Laravel to attempt connection to a non-existent, wrong, or inaccessible database server/database schema. - Database Not Created: The database specified by
DB_DATABASEin your.envfile simply does not exist on your MySQL or PostgreSQL server. Laravel tries to connect to it but finds no such schema. - Insufficient Database User Permissions: The
DBUSERNAMEuser specified in.envlacks the necessary privileges (e.g.,CREATE,ALTER,DROP) to create tables in the specifiedDBDATABASE. - Configuration Cache Issues: Laravel caches its configuration for performance. If you've recently changed your
.envfile, especially database credentials, the cached configuration might still be pointing to old, invalid settings. - Missing PHP Database Extensions: The required PHP Data Objects (PDO) extension for your database type (e.g.,
php-mysqlorphp-pgsql) is not installed or enabled for your PHP version. - Incorrect Working Directory: The
php artisan migratecommand is executed from a directory other than your Laravel project root, causing it to fail to load the correct.envfile or application context. - Docker/Containerization Issues: When running Laravel in Docker, the database service might not be properly linked, reachable, or its hostname/port is incorrectly configured within the Laravel container's
.env. Persistent volumes for the database might also be missing or misconfigured, leading to data loss on container restarts.
Step-by-Step Resolution
Follow these steps sequentially to diagnose and resolve the SQLSTATE[42S02] error.
1. Verify Database Existence and Connectivity
First, confirm that the target database actually exists on your database server and that you can connect to it.
- Check
.envfile: Open your Laravel project's.envfile and note theDBCONNECTION,DBHOST,DBPORT,DBDATABASE,DBUSERNAME, andDBPASSWORDvalues. -
`env - DB_CONNECTION=mysql # or pgsql
- DB_HOST=127.0.0.1
- DB_PORT=3306 # or 5432 for PostgreSQL
- DBDATABASE=yourlaravel_db
- DBUSERNAME=yourdb_user
- DBPASSWORD=yourdb_password
-
` - Access your database server: Log in to your database server (e.g., via SSH to the machine hosting MySQL/PostgreSQL).
- Check database existence:
- * For MySQL:
-
`bash - mysql -u yourdbuser -p -h DBHOST -P DBPORT
- # Enter yourdbpassword when prompted
- SHOW DATABASES;
- USE yourlaraveldb; # Attempt to select the database
-
` - * For PostgreSQL:
-
`bash - psql -U yourdbuser -h DBHOST -p DBPORT -d yourlaraveldb
- # Enter yourdbpassword when prompted
- l # List databases
- c yourlaraveldb # Attempt to connect to the database
-
` - Create database if missing: If
yourlaraveldbdoes not appear in the list of databases or you cannot connect to it, create it manually: - * For MySQL: (Login as root or a privileged user)
-
`bash - CREATE DATABASE yourlaraveldb CHARACTER SET utf8mb4 COLLATE utf8mb4unicodeci;
-
` - * For PostgreSQL: (Login as postgres or a privileged user)
-
`bash - CREATE DATABASE yourlaraveldb ENCODING 'UTF8' LCCOLLATE 'enUS.UTF-8' LCCTYPE 'enUS.UTF-8' TEMPLATE template0;
-
` - > [!IMPORTANT]
- > Ensure that the
DB_HOSTis correctly set.127.0.0.1orlocalhostis common for local/same-server databases. If your database is on a different server, use its IP address or hostname.
2. Inspect and Correct .env Database Credentials
Even if the database exists, incorrect credentials will prevent Laravel from accessing it.
- Re-verify
.env: Double-check all database-related entries in your.envfile against your actual database server configuration. Pay close attention to: - *
DB_HOST: Should be the IP or hostname of the database server. - *
DB_PORT: Default is3306for MySQL,5432for PostgreSQL. - *
DB_DATABASE: The exact name of the database. - *
DBUSERNAME: The username with access toDBDATABASE. - *
DBPASSWORD: The password forDBUSERNAME. - *
> [!WARNING]Ensure that passwords or usernames containing special characters (like#,$,!) are correctly escaped or quoted in your.envfile if necessary, though Laravel generally handles this well. For robust passwords, consider avoiding some shell-special characters.
- Test connection with correct details: Attempt to connect to the database again using the exact values from your
.envfile, as shown in Step 1.
3. Ensure Database User Privileges
The DBUSERNAME user must have sufficient permissions to create, alter, and drop tables within yourlaravel_db.
- Login to your database server as a privileged user: For example, as
rootfor MySQL orpostgresfor PostgreSQL. - Grant permissions:
- * For MySQL:
-
`sql - — If the user doesn't exist, create it first
- CREATE USER 'yourdbuser'@'DBHOST' IDENTIFIED BY 'yourdb_password';
- — Grant all privileges on yourlaraveldb to the user
- GRANT ALL PRIVILEGES ON yourlaraveldb.* TO 'yourdbuser'@'DB_HOST';
- FLUSH PRIVILEGES;
-
` - Replace
DB_HOSTwithlocalhost,127.0.0.1, or%(for any host – use with caution in production). - * For PostgreSQL:
-
`sql - — Connect to the postgres default database
- c postgres
- — If the user doesn't exist, create it first
- CREATE USER yourdbuser WITH PASSWORD 'yourdbpassword';
- — Grant all privileges on yourlaraveldb to the user
- GRANT ALL PRIVILEGES ON DATABASE yourlaraveldb TO yourdbuser;
-
` - > [!WARNING]
- > Granting
ALL PRIVILEGESis common for development. In production, consider granting only the minimum necessary privileges (SELECT,INSERT,UPDATE,DELETE,CREATE,ALTER,DROP,INDEX,REFERENCES) for better security.
4. Clear Laravel Configuration Cache
Laravel caches configuration files to speed up application loading. If you've recently modified .env, the cached version might be stale.
- Navigate to your Laravel project root:
-
`bash - cd /var/www/html/yourlaravelapp
-
` - Clear caches:
-
`bash - php artisan config:clear
- php artisan cache:clear
- php artisan view:clear
- # For Laravel 8+
- php artisan optimize:clear
-
` - Attempt migration again:
-
`bash - php artisan migrate
-
`
5. Install Missing PHP Database Extensions
Laravel relies on PHP's PDO extensions to communicate with databases. If these are missing, connections will fail.
- Identify your PHP version:
-
`bash - php -v
-
` - (e.g.,
PHP 7.4.3orPHP 8.1.10) - Install the correct PDO extension:
- * For MySQL:
-
`bash - sudo apt update
- sudo apt install php7.4-mysql # Replace 7.4 with your PHP version (e.g., php8.1-mysql)
-
` - * For PostgreSQL:
-
`bash - sudo apt update
- sudo apt install php7.4-pgsql # Replace 7.4 with your PHP version (e.g., php8.1-pgsql)
-
` - Restart PHP-FPM or Apache:
- * For Nginx with PHP-FPM:
-
`bash - sudo systemctl restart php7.4-fpm.service # Adjust service name for your PHP version
-
` - * For Apache:
-
`bash - sudo systemctl restart apache2.service
-
` - Verify extension: You can check if the extension is loaded:
-
`bash - php -m | grep pdomysql # or pdopgsql
-
` - It should output
pdomysqlorpdopgsql.
6. Check File Permissions
Incorrect file permissions on Laravel's storage and bootstrap/cache directories can prevent it from writing necessary files, sometimes leading to unexpected errors.
- Navigate to your Laravel project root:
-
`bash - cd /var/www/html/yourlaravelapp
-
` - Set correct ownership and permissions: Assuming your web server user is
www-data(common on Ubuntu) and your application root is/var/www/html/yourlaravelapp: -
`bash - sudo chown -R www-data:www-data /var/www/html/yourlaravelapp
- sudo find /var/www/html/yourlaravelapp -type d -exec chmod 755 {} ;
- sudo find /var/www/html/yourlaravelapp -type f -exec chmod 644 {} ;
- sudo chmod -R 775 /var/www/html/yourlaravelapp/storage
- sudo chmod -R 775 /var/www/html/yourlaravelapp/bootstrap/cache
-
` - > [!IMPORTANT]
- > The
storageandbootstrap/cachedirectories, along with their contents, must be writable by the web server user. If you use a different user/group for your web server (e.g., a custom FPM pool user), adjustwww-dataaccordingly.
7. If Using Docker/Docker Compose
When deploying with Docker, network connectivity and service naming are critical.
- Verify service names and network:
- * Open your
docker-compose.ymlfile. - * Ensure the
DB_HOSTin your Laravel container's.env(or environment variables indocker-compose.yml) matches the service name of your database container (e.g.,dbormysql). - * Example
docker-compose.ymlsnippet: -
`yaml - services:
- app:
- build: .
- environment:
- DB_HOST: db # This MUST match the database service name below
- DBDATABASE: yourlaravel_db
- DBUSERNAME: yourdb_user
- DBPASSWORD: yourdb_password
- depends_on:
- – db
- db:
- image: mysql:8.0 # or postgres:12
- environment:
- MYSQLDATABASE: yourlaravel_db
- MYSQLUSER: yourdb_user
- MYSQLPASSWORD: yourdb_password
- MYSQLROOTPASSWORD: root_password
- volumes:
- – db_data:/var/lib/mysql
- volumes:
- db_data:
-
` - Check database container status:
-
`bash - docker-compose ps
-
` - Ensure your database service (
dbormysql) isUp. - Test connectivity from inside the Laravel container:
-
`bash - docker exec -it <yourlaravelappcontainername> bash
- php artisan tinker
-
` - Inside tinker, try to connect:
-
`php - DB::connection()->getPdo();
-
` - If successful, it should return a PDO object. If it throws an error, it indicates a connectivity issue from within the container.
- Rebuild and restart: Sometimes, container network issues can persist. A full rebuild and restart can help:
-
`bash - docker-compose down –volumes
- docker-compose up –build -d
-
` - Then, attempt
php artisan migratefrom within the Laravel container: -
`bash - docker exec -it <yourlaravelappcontainername> php artisan migrate
-
`
8. Verify Laravel Application Path
Ensure you are executing php artisan migrate from the root directory of your Laravel project, where the artisan script and .env file are located.
- Check current directory:
-
`bash - pwd
-
` - List files:
-
`bash - ls -F
-
` - You should see
artisan,.env,app/,bootstrap/,config/, etc. If not,cdinto the correct directory.
After performing these steps, re-run php artisan migrate. If the issue persists, carefully review your terminal output for any new error messages that might point to a different problem.
Leave a Reply