Runtimes Intermediate

Troubleshooting Laravel artisan migrate SQLSTATE: Base Table or View Not Found on CentOS Stream / Rocky Linux

Resolve 'SQLSTATE base table or view not found' when running Laravel migrations on CentOS Stream or Rocky Linux, often due to database connection issues or caching.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve 'SQLSTATE base table or view not found' when running Laravel migrations on CentOS Stream or Rocky Linux, often due to database connection issues or caching.

Introduction

Encountering the SQLSTATE[42S02]: Base table or view not found error during a Laravel artisan migrate command is a common frustration for developers and system administrators. This error indicates that Laravel's database interaction is failing because it expects a specific table or view to exist in the configured database, but cannot find it. While the message is specific, the underlying causes can range from incorrect database credentials and connectivity issues to missing database tables or even environmental caching problems, particularly on CentOS Stream or Rocky Linux environments where firewalls and SELinux are often enabled by default.

This guide will walk you through a systematic troubleshooting process to diagnose and resolve this issue, focusing on the specific considerations for RHEL-based distributions like CentOS Stream and Rocky Linux.

Symptom & Error Signature

When you attempt to run php artisan migrate in your terminal, the command execution will halt, displaying an error similar to the following:

php artisan migrate

   IlluminateDatabaseQueryException

  SQLSTATE[42S02]: Base table or view not found: 1146 Table 'your_database_name.migrations' doesn't exist (SQL: select `migration` from `migrations` order by `batch` asc, `migration` asc)

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:795
    791|         // If an exception occurs when attempting to run a query, we'll format the error
    792|         // message to include the bindings with the query so that it's much easier
    793|         // to debug the error that occurred during the execution of the query.
    794|         catch (Exception $e) {
    795|             throw new QueryException(
    796|                 $query, $this->prepareBindings($bindings), $e
    797|             );
    798|         }
    799|

Or, more generally, if the error is related to any other table your application might query during the migration process (e.g., within a seeder or migration file itself):

php artisan migrate

   IlluminateDatabaseQueryException

  SQLSTATE[42S02]: Base table or view not found: 1146 Table 'your_database_name.users' doesn't exist (SQL: select * from `users` where `id` = 1 limit 1)

The key part of the error is SQLSTATE[42S02]: Base table or view not found: 1146 Table 'your_database_name.some_table' doesn't exist.

Root Cause Analysis

This error fundamentally means Laravel's database layer attempted to perform an operation on a table that it could not locate in the specified database. The most common underlying reasons include:

  1. Incorrect Database Connection Details: The .env file contains wrong credentials (host, port, database name, username, password), leading Laravel to connect to a non-existent database, the wrong database, or fail to connect entirely. This is the most frequent culprit.
  2. Database Not Created or Inaccessible: The database specified in DB_DATABASE in your .env file does not exist on your MariaDB/MySQL server, or the specified DB_USERNAME lacks the necessary privileges to access it.
  3. Missing migrations Table: For fresh installations or after certain database resets, the crucial migrations table (which Laravel uses to track executed migrations) might not exist. artisan migrate will try to read this table first.
  4. Laravel Configuration Cache Issues: Stale configuration data, particularly cached database credentials, can cause artisan commands to use outdated information even if the .env file has been updated.
  5. Database Server Offline or Inaccessible: The MariaDB/MySQL server might not be running, or a firewall (like firewalld on CentOS Stream/Rocky Linux) might be blocking the connection from your application server.
  6. SELinux Policy Restrictions: Less common for artisan CLI commands directly, but SELinux could potentially interfere with PHP's ability to read .env files or establish network connections if contexts are misconfigured, especially in a hardened environment.

Step-by-Step Resolution

Follow these steps systematically to pinpoint and resolve the issue.

1. Verify and Correct Database Connection Details in .env

This is the most common cause. Double-check every detail in your project's .env file.

# Navigate to your Laravel project directory
cd /var/www/your_laravel_app
nano .env

Ensure the following variables are correctly set for your database:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1   # Or your remote database IP/hostname
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password

Verify that DB_HOST is correct. If your database is on the same server, 127.0.0.1 or localhost is common. If it's a remote database, use its IP address or hostname. Ensure DB_PORT is correct (default for MySQL/MariaDB is 3306).

[!WARNING] After modifying .env, always clear Laravel's configuration cache. See Step 3.

2. Test Database Server Connectivity and Status

Confirm that your MariaDB/MySQL server is running and accessible.

# Check database server status
sudo systemctl status mariadb # For MariaDB
# OR
sudo systemctl status mysqld  # For MySQL

# Expected output should show 'active (running)'
# If not running, start it:
sudo systemctl start mariadb
sudo systemctl enable mariadb

Next, test connectivity from your application server to the database server using telnet or nc.

# Install net-tools if not already present
sudo dnf install telnet nc -y

# Test connection to the database host and port
telnet DB_HOST DB_PORT
# Example: telnet 127.0.0.1 3306
# Expected output: Connected to 127.0.0.1. Escape character is '^]'.
# If it hangs or shows 'Connection refused', there's a network or firewall issue.

If telnet fails, check your firewall configuration on the database server (if separate) or your application server.

# List active firewalld rules on CentOS Stream/Rocky Linux
sudo firewall-cmd --list-all

# If your database is remote and firewalld is blocking, you might need to open port 3306
# ONLY IF the database is external AND you need to reach it.
# Usually, localhost connections don't need firewalld rules.
# This example allows connections from the *current* server to the database server.
# It's more common to configure this on the DB server itself to allow connections
# from the web server's IP.
# If connecting from localhost, no firewall rule is needed for 3306.

# If MariaDB/MySQL is on the same server and you're using a remote DB_HOST,
# ensure the remote DB server's firewall allows your current server's IP.
# If DB_HOST is 127.0.0.1, firewalld is unlikely the cause unless it's blocking PHP.

3. Clear Laravel Caches

Laravel aggressively caches configuration. Even if you update your .env file, the artisan command might still be using old cached values.

# Navigate to your Laravel project directory
cd /var/www/your_laravel_app

# Clear configuration cache
php artisan config:clear

# Clear other caches that might indirectly affect env loading
php artisan cache:clear
php artisan view:clear
php artisan route:clear

# Re-optimize composer autoload files
composer dump-autoload

# Important: Restart PHP-FPM if you're deploying web changes,
# though not strictly necessary for CLI 'artisan' commands
sudo systemctl restart php-fpm

4. Ensure Database Exists and User Has Privileges

Even with correct connection details, the specified database might not exist, or the user might lack permissions.

# Connect to your MariaDB/MySQL server as root or an admin user
mysql -u root -p

Once connected, perform the following checks:

-- Verify the database exists
SHOW DATABASES;
-- Ensure 'your_database_name' from your .env is in the list.
-- If not, create it:
CREATE DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Verify user privileges for 'your_db_user'@'DB_HOST' (from .env)
SELECT user, host FROM mysql.user; -- Check if user exists

-- Show grants for your user (replace 'your_db_user' and 'DB_HOST')
SHOW GRANTS FOR 'your_db_user'@'localhost'; -- Or '127.0.0.1', or '%', or your remote DB_HOST

-- If the user doesn't exist or lacks privileges, create/grant them.
-- Example for a local user:
CREATE USER 'your_db_user'@'localhost' IDENTIFIED BY 'your_db_password';
GRANT ALL PRIVILEGES ON your_database_name.* TO 'your_db_user'@'localhost';
FLUSH PRIVILEGES; -- Apply changes

Granting ALL PRIVILEGES is convenient for development but consider more restrictive permissions for production environments (e.g., SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER on specific databases).

5. Handle Missing migrations Table

If you've confirmed database connectivity and credentials, but the error specifically mentions your_database_name.migrations doesn't exist, it means Laravel's migration tracking table is missing.

# Navigate to your Laravel project directory
cd /var/www/your_laravel_app

# Create the 'migrations' table
php artisan migrate:install

# Now, run your migrations
php artisan migrate

php artisan migrate:install will create a single migrations table in your database. Once this table exists, php artisan migrate can proceed to execute all pending migrations.

6. Check File Permissions and SELinux (CentOS Stream / Rocky Linux Specific)

While less common for SQLSTATE errors during artisan migrate, incorrect file permissions or SELinux policies could prevent PHP from reading the .env file or accessing temporary directories, leading to unexpected behavior.

# Navigate to your Laravel project directory
cd /var/www/your_laravel_app

# Check .env file permissions
ls -l .env
# Ensure the user running `php artisan` (typically your SSH user) has read access.
# Common safe permissions: 644 or 600
sudo chmod 644 .env

# Check storage directory permissions
ls -ld storage bootstrap/cache
# Ensure the `storage` and `bootstrap/cache` directories are writable by the user
# running `php artisan` and your web server user (e.g., `nginx` or `www-data`).
sudo chown -R your_user:your_group storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache

SELinux Troubleshooting:

SELinux can be complex. If you suspect it, you can temporarily disable it for testing, but do not do this in production environments without understanding the implications.

# Check current SELinux status
sestatus

# Temporarily disable SELinux (for testing ONLY!)
sudo setenforce 0

# Try running your migration again
php artisan migrate

# Re-enable SELinux
sudo setenforce 1

If the migration succeeds with SELinux disabled, you have identified the problem. You'll need to create a custom SELinux policy or adjust existing contexts. Look for AVC (Access Vector Cache) denials in the audit logs:

sudo tail -f /var/log/audit/audit.log

Run php artisan migrate again, and observe new denials. You can use audit2allow to generate policy modules. For example, if php is denied network access:

sudo ausearch -c 'php' --raw | audit2allow -M my-php-policy
sudo semodule -i my-php-policy.pp

This guide covers the most common scenarios and resolutions for SQLSTATE[42S02]: Base table or view not found when running Laravel migrations on CentOS Stream and Rocky Linux. By systematically checking your .env, database connectivity, permissions, and caches, you should be able to resolve this issue efficiently.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn →

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.