{"id":55,"date":"2026-07-13T00:00:00","date_gmt":"2026-07-13T00:00:00","guid":{"rendered":"http:\/\/\/var\/www\/html\/?p=55"},"modified":"2026-07-21T01:02:32","modified_gmt":"2026-07-21T01:02:32","slug":"laravel-artisan-migrate-sqlstate-base-table-or-view-not-found-on-macos-local-environment","status":"publish","type":"post","link":"https:\/\/butitworkedlocal.com\/laravel-artisan-migrate-sqlstate-base-table-or-view-not-found-on-macos-local-environment\/","title":{"rendered":"Troubleshooting: Laravel `artisan migrate` SQLSTATE Base Table or View Not Found on macOS Local Environment"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Resolve the &#039;SQLSTATE base table or view not found&#039; error during Laravel migrations on macOS. This guide covers common causes and fixes for local development setups.<\/strong><\/p>\n\n\n<h2>Introduction<\/h2>\n<p>Encountering a <code>SQLSTATE base table or view not found<\/code> error while running <code>php artisan migrate<\/code> in your Laravel project on a macOS local development environment can be frustrating. This error typically indicates that your Laravel application is unable to locate or interact with expected database tables, such as the <code>migrations<\/code> table or other application-specific tables, despite seemingly connecting to the database. This guide will walk you through the common causes and provide a systematic approach to resolve this issue, ensuring your development workflow remains smooth.<\/p>\n<h3>Symptom &amp; Error Signature<\/h3>\n<p>When you execute <code>php artisan migrate<\/code> in your terminal, you might see output similar to this:<\/p>\n<pre><code class=\"language-bash\">php artisan migrate\n<\/code><\/pre>\n<pre><code>   INFO  Running migrations.\n\n  2023_01_01_000000_create_users_table ..................................................................................... RUNNING\n  2023_01_01_000000_create_users_table ..................................................................................... FAILED\n\n   IlluminateDatabaseQueryException\n\n  SQLSTATE[42S02]: Base table or view not found: 1146 Table &#039;your_database_name.users&#039; doesn&#039;t exist (SQL: create table `users` (`id` bigint unsigned not null auto_increment primary key, `name` varchar(255) not null, `email` varchar(255) not null, `email_verified_at` timestamp null, `password` varchar(255) not null, `remember_token` varchar(100) null, `created_at` timestamp null, `updated_at` timestamp null) default character set utf8mb4 collate utf8mb4_unicode_ci)\n\n  at vendor\/laravel\/framework\/src\/Illuminate\/Database\/Connection.php:826\n    822|         \/\/ If an exception occurs while attempting to run a query, we&#039;ll format the error\n    823|         \/\/ message to include the bindings with the query, which will make it much\n    824|         \/\/ easier to debug whilst still getting the actual exception instance.\n    825|         catch (Exception $e) {\n  &gt; 826|             throw new QueryException(\n    827|                 $query, $this-&gt;prepareBindings($bindings), $e\n    828|             );\n    829|         }\n    830|\n<\/code><\/pre>\n<p>The key part of the error message is <code>SQLSTATE[42S02]: Base table or view not found<\/code>. This usually occurs when Laravel attempts to create the <code>migrations<\/code> table (to track executed migrations) or your first application table (like <code>users<\/code>) and cannot find it or the database itself isn&#039;t correctly set up or targeted.<\/p>\n<h3>Root Cause Analysis<\/h3>\n<p>This error, specifically <code>SQLSTATE[42S02]: Base table or view not found<\/code>, primarily indicates that while your Laravel application successfully <em>connected<\/em> to a database server, it could not find a specific database or table it was trying to access or create. The most common underlying reasons for this on a macOS local environment include:<\/p>\n<ol>\n<li><strong>Incorrect Database Configuration:<\/strong> The <code>.env<\/code> file contains incorrect database credentials, host, port, or database name, leading Laravel to connect to the wrong database server, a non-existent database, or a database where the specified table truly doesn&#039;t exist.<\/li>\n<li><strong>Database Service Not Running:<\/strong> The MySQL or PostgreSQL database server (or its Docker container) is not currently running on your macOS machine. Laravel might fail to establish a connection, or worse, connect to a <em>different<\/em> local database instance that is running (e.g., a default system-level database or another project&#039;s database).<\/li>\n<li><strong>Database Not Created:<\/strong> The database specified in your <code>.env<\/code> file (e.g., <code>DB_DATABASE=your_app_db<\/code>) has not been manually created on your database server. Laravel&#039;s migration command doesn&#039;t create the database itself; it only creates tables within an <em>existing<\/em> database.<\/li>\n<li><strong>Stale Configuration Cache:<\/strong> Laravel&#039;s configuration might be cached, causing it to use outdated database credentials even after you&#039;ve updated your <code>.env<\/code> file.<\/li>\n<li><strong>Insufficient Database User Privileges:<\/strong> The database user specified in <code>.env<\/code> (e.g., <code>DB_USERNAME=root<\/code>) lacks the necessary permissions to create tables or access the specified database.<\/li>\n<li><strong>Conflicting Database Services:<\/strong> Multiple database services (e.g., Homebrew MySQL and a Dockerized MySQL instance) might be running simultaneously, leading to confusion about which database server Laravel is connecting to.<\/li>\n<li><strong>Docker\/Laravel Sail Specific Issues:<\/strong> If using Docker, the database container might not be healthy, or its internal hostname\/port mapping might be misconfigured.<\/li>\n<\/ol>\n<h3>Step-by-Step Resolution<\/h3>\n<p>Follow these steps to diagnose and resolve the <code>SQLSTATE base table or view not found<\/code> error.<\/p>\n<h4>1. Verify Database Service Status<\/h4>\n<p>Ensure your database server (MySQL, PostgreSQL, or Docker container) is actively running.<\/p>\n<p><strong>For Homebrew-installed MySQL\/PostgreSQL:<\/strong><\/p>\n<pre><code class=\"language-bash\"># To check MySQL status\nbrew services list | grep mysql\n# Expected output: mysql started your_user_name \/path\/to\/mysql.plist\n\n# To check PostgreSQL status\nbrew services list | grep postgresql\n# Expected output: postgresql started your_user_name \/path\/to\/postgresql.plist\n<\/code><\/pre>\n<p>If the service is not <code>started<\/code>, start it:<\/p>\n<pre><code class=\"language-bash\">brew services start mysql\n# OR\nbrew services start postgresql\n<\/code><\/pre>\n<p><strong>For Docker\/Laravel Sail:<\/strong><\/p>\n<pre><code class=\"language-bash\"># Navigate to your Laravel project root\ncd \/path\/to\/your\/laravel\/project\n\n# Check running Docker containers\ndocker ps -a\n# OR if using docker compose directly\ndocker compose ps -a\n<\/code><\/pre>\n<p>Look for containers named similar to <code>your_project_name-mysql-1<\/code> or <code>your_project_name-pgsql-1<\/code>. Ensure their <code>STATUS<\/code> is <code>Up<\/code>. If they are stopped or exited:<\/p>\n<pre><code class=\"language-bash\"># For Laravel Sail\nsail up -d\n\n# For generic Docker Compose\ndocker compose up -d\n<\/code><\/pre>\n<blockquote class=\"important\"><p>Always ensure your database service is running before attempting any database operations with Laravel.<\/p>\n<\/blockquote>\n<h4>2. Inspect <code>.env<\/code> Configuration<\/h4>\n<p>The <code>.env<\/code> file is crucial for local development. Double-check every database-related entry.<\/p>\n<pre><code class=\"language-bash\"># Open your .env file in a text editor\nnano .env\n<\/code><\/pre>\n<p>Review the <code>DB_CONNECTION<\/code>, <code>DB_HOST<\/code>, <code>DB_PORT<\/code>, <code>DB_DATABASE<\/code>, <code>DB_USERNAME<\/code>, and <code>DB_PASSWORD<\/code> variables.<\/p>\n<p><strong>Example for MySQL:<\/strong><\/p>\n<pre><code class=\"language-ini\">DB_CONNECTION=mysql\nDB_HOST=127.0.0.1      # Or localhost. If using Docker, it might be the service name (e.g., mysql or db)\nDB_PORT=3306           # Standard MySQL port\nDB_DATABASE=your_app_db_name # IMPORTANT: This must be an existing database\nDB_USERNAME=root       # Or your database user\nDB_PASSWORD=            # Or your database user&#039;s password\n<\/code><\/pre>\n<p><strong>Example for PostgreSQL:<\/strong><\/p>\n<pre><code class=\"language-ini\">DB_CONNECTION=pgsql\nDB_HOST=127.0.0.1      # Or localhost. If using Docker, it might be the service name (e.g., pgsql or db)\nDB_PORT=5432           # Standard PostgreSQL port\nDB_DATABASE=your_app_db_name # IMPORTANT: This must be an existing database\nDB_USERNAME=postgres   # Or your database user\nDB_PASSWORD=secret      # Or your database user&#039;s password\n<\/code><\/pre>\n<blockquote class=\"important\"><p>Pay close attention to <code>DB_HOST<\/code>. For Docker\/Laravel Sail, <code>DB_HOST<\/code> should typically be the service name defined in <code>docker-compose.yml<\/code> (e.g., <code>mysql<\/code> or <code>db<\/code>), <em>not<\/em> <code>127.0.0.1<\/code> unless port mapping is explicitly used for external access. For Valet\/Herd, <code>127.0.0.1<\/code> or <code>localhost<\/code> is usually correct.<\/p>\n<\/blockquote>\n<h4>3. Confirm Database Existence and Accessibility<\/h4>\n<p>Laravel&#039;s <code>artisan migrate<\/code> command expects the database specified in <code>DB_DATABASE<\/code> to already exist. It does not create the database itself.<\/p>\n<p><strong>Connect via <code>mysql<\/code> client (for MySQL):<\/strong><\/p>\n<pre><code class=\"language-bash\">mysql -u DB_USERNAME -p -h DB_HOST -P DB_PORT\n# Example: mysql -u root -p -h 127.0.0.1 -P 3306\n# Enter password when prompted.\n<\/code><\/pre>\n<p>Once connected, list existing databases:<\/p>\n<pre><code class=\"language-sql\">SHOW DATABASES;\n<\/code><\/pre>\n<p>If your <code>DB_DATABASE<\/code> is not listed, create it:<\/p>\n<pre><code class=\"language-sql\">CREATE DATABASE your_app_db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n<\/code><\/pre>\n<p>Then exit the client:<\/p>\n<pre><code class=\"language-sql\">EXIT;\n<\/code><\/pre>\n<p><strong>Connect via <code>psql<\/code> client (for PostgreSQL):<\/strong><\/p>\n<pre><code class=\"language-bash\">psql -U DB_USERNAME -h DB_HOST -p DB_PORT\n# Example: psql -U postgres -h 127.0.0.1 -p 5432\n# Enter password when prompted.\n<\/code><\/pre>\n<p>Once connected, list existing databases:<\/p>\n<pre><code class=\"language-sql\">l\n<\/code><\/pre>\n<p>If your <code>DB_DATABASE<\/code> is not listed, create it:<\/p>\n<pre><code class=\"language-sql\">CREATE DATABASE your_app_db_name;\n<\/code><\/pre>\n<p>Then exit the client:<\/p>\n<pre><code class=\"language-sql\">q\n<\/code><\/pre>\n<h4>4. Clear Laravel Configuration Caches<\/h4>\n<p>Stale cached configuration can prevent Laravel from reading your updated <code>.env<\/code> file correctly. Always clear caches after making changes to <code>.env<\/code> or configuration files.<\/p>\n<pre><code class=\"language-bash\">php artisan cache:clear\nphp artisan config:clear\nphp artisan route:clear\nphp artisan view:clear\ncomposer dump-autoload\n<\/code><\/pre>\n<blockquote class=\"important\"><p>Running <code>php artisan config:clear<\/code> is particularly important after modifying the <code>.env<\/code> file, as Laravel&#039;s configuration cache can override <code>.env<\/code> variables.<\/p>\n<\/blockquote>\n<h4>5. Verify Database User Privileges<\/h4>\n<p>Ensure the database user (e.g., <code>root<\/code>, <code>postgres<\/code>, or a custom user) specified in your <code>.env<\/code> has sufficient privileges to create, alter, and drop tables on the database.<\/p>\n<p><strong>For MySQL (connected as a privileged user like <code>root<\/code>):<\/strong><\/p>\n<pre><code class=\"language-sql\">-- Grant all privileges to &#039;your_username&#039; on &#039;your_app_db_name&#039;\nGRANT ALL PRIVILEGES ON your_app_db_name.* TO &#039;your_username&#039;@&#039;localhost&#039; IDENTIFIED BY &#039;your_password&#039;;\nFLUSH PRIVILEGES;\n<\/code><\/pre>\n<p>Replace <code>your_username<\/code>, <code>your_password<\/code>, <code>your_app_db_name<\/code>, and <code>localhost<\/code> with your specific values. If <code>DB_HOST<\/code> in <code>.env<\/code> is <code>127.0.0.1<\/code>, use <code>&#039;your_username&#039;@&#039;127.0.0.1&#039;<\/code>. If using Docker, it might be <code>&#039;your_username&#039;@&#039;%&#039;<\/code> for any host, but be cautious with <code>root<\/code> for security.<\/p>\n<p><strong>For PostgreSQL (connected as a privileged user like <code>postgres<\/code>):<\/strong><\/p>\n<pre><code class=\"language-sql\">-- Grant all privileges on database &#039;your_app_db_name&#039; to &#039;your_username&#039;\nGRANT ALL PRIVILEGES ON DATABASE your_app_db_name TO your_username;\n<\/code><\/pre>\n<h4>6. Re-run Migrations<\/h4>\n<p>After performing the above checks and corrections, attempt to run your migrations again.<\/p>\n<pre><code class=\"language-bash\">php artisan migrate\n<\/code><\/pre>\n<p>If you previously ran some migrations on a different or corrupted database, and you are starting fresh, you might consider:<\/p>\n<pre><code class=\"language-bash\">&gt; [!WARNING]\n&gt; `php artisan migrate:fresh` will drop *all tables* from your database before running migrations. Only use this if you are confident you don&#039;t need existing data, especially in a local development environment.\n\nphp artisan migrate:fresh --seed # Drops all tables, runs migrations, and then runs seeders\n<\/code><\/pre>\n<h4>7. Specific Environment Considerations (Docker\/Laravel Sail, Valet\/Herd)<\/h4>\n<p><strong>For Laravel Sail (Docker):<\/strong><\/p>\n<ul>\n<li>If you&#039;re using Sail, <code>DB_HOST<\/code> in your <code>.env<\/code> should usually be <code>mysql<\/code> (for MySQL) or <code>pgsql<\/code> (for PostgreSQL), as defined in your <code>docker-compose.yml<\/code>.<\/li>\n<li>Ensure the Sail containers are healthy: <code>sail ps<\/code>. If issues persist, try rebuilding and restarting:<pre><code class=\"language-bash\">sail down --rmi all -v # Removes containers, images, and volumes (data loss for DB)\nsail up -d\nsail artisan migrate # Use sail artisan instead of php artisan\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<p><strong>For Laravel Valet\/Herd:<\/strong><\/p>\n<ul>\n<li>Valet and Herd manage services (PHP, Nginx, MySQL\/PostgreSQL) via Homebrew. Ensure they are running as described in step 1.<\/li>\n<li>Sometimes, a simple restart helps:<pre><code class=\"language-bash\">valet restart\n# OR\nherd restart\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<h4>8. Check for Other Processes on Database Port<\/h4>\n<p>Ensure no other applications are using the default database port (e.g., 3306 for MySQL, 5432 for PostgreSQL). This can lead to connection issues.<\/p>\n<pre><code class=\"language-bash\"># For MySQL (port 3306)\nsudo lsof -i :3306\n\n# For PostgreSQL (port 5432)\nsudo lsof -i :5432\n<\/code><\/pre>\n<p>If another process is listening, identify it and stop it, or configure your database (and Laravel) to use a different port.<\/p>\n<p>By systematically working through these steps, you should be able to identify and resolve the <code>SQLSTATE base table or view not found<\/code> error, allowing your Laravel migrations to run successfully on your macOS local development environment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Resolve the &#8216;SQLSTATE base table or view not found&#8217; error during Laravel migrations on macOS. This guide covers common causes and fixes for local development setups.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63],"tags":[147,40,146,47,148,149,65,150,151],"class_list":["post-55","post","type-post","status-publish","format-standard","hentry","category-runtimes","tag-artisan","tag-devops","tag-laravel","tag-macos","tag-migration","tag-mysql","tag-php","tag-postgresql","tag-sqlstate"],"_links":{"self":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/55","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/comments?post=55"}],"version-history":[{"count":2,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/55\/revisions"}],"predecessor-version":[{"id":302,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/posts\/55\/revisions\/302"}],"wp:attachment":[{"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/media?parent=55"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/categories?post=55"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/butitworkedlocal.com\/wp-json\/wp\/v2\/tags?post=55"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}