WordPress Database Error: Table Doesn't Exist — Read the Table Name First
The log line names the missing table and the code that asked for it. A core table, a plugin's table and a table with the wrong prefix are three different problems, and only one of them is fixed by reactivating a plugin.
WordPress ran a query against a table that is not in the database, and the log line tells you exactly which table and which code asked for it. A typical entry reads WordPress database error Table 'shop_db.wp_wc_orders' doesn't exist for query SELECT … made by require('wp-blog-header.php'), …, Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore->read. Everything you need is in those three parts: the table name, the query, and the call stack after "made by".
Where the message comes from
wpdb::print_error() formats every failed query as WordPress database error %1$s for query %2$s made by %3$s and sends it to error_log() unless errors are suppressed. The "made by" part is a backtrace summary of the PHP functions that led to the query. Printing on the page is a second, optional step: wpdb enables it only when WP_DEBUG and WP_DEBUG_DISPLAY are both true, and then shows a shorter box with "WordPress database error:" and the query.
So the log, not the screen, is your source. With debug logging on it is wp-content/debug.log; otherwise it is the server's PHP error log.
Classify the table name
The table name in quotes is database.table. Compare the table part with your $table_prefix in wp-config.php:
| Table in the error | Diagnosis |
|---|---|
Your prefix + a core name (wp_options, wp_postmeta, wp_termmeta…) |
A core table is missing |
Your prefix + a plugin's name (wp_wc_orders, wp_yoast_indexable…) |
A plugin's table was never created or was lost |
A different prefix than wp-config.php (wp_ vs wpx7_) |
Code is using a hard-coded prefix, or the prefix changed |
Right prefix, different letter case (wp_Posts_Stats) |
Case sensitivity after moving from Windows or macOS to Linux |
List what is actually there before changing anything:
wp db query "SHOW TABLES LIKE '%options%'"
wp db tables --all-tables-with-prefix
A core table is missing
If wp_options is the table that is gone while others remain, WordPress cannot read the site URL and stops with "One or more database tables are unavailable. The database may need to be repaired." That suggestion misleads: the repair screen enabled by WP_ALLOW_REPAIR runs CHECK TABLE and REPAIR TABLE on existing tables, and cannot create a missing one.
Restore from backup first — a missing core table means data is gone, and an empty recreated table does not bring it back. If the table held nothing you need (an empty wp_termmeta on a small site, for instance), recreate it from core's schema. dbDelta() with no queries uses WordPress's own schema and creates whatever is missing; existing tables are only brought in line with that schema, not emptied:
wp eval 'require_once ABSPATH . "wp-admin/includes/upgrade.php"; make_db_current_silent();'
The usual cause is a partial import: a dump that stopped partway, or a migration tool that copied a filtered list of tables. Check the import for the error that stopped it before importing again. Partial imports are also a frequent cause of Error establishing a database connection when wp_options is the table that failed.
A plugin's table is missing
Most plugins create their tables in their activation routine, and many then record a schema version in wp_options so they only run the install again on upgrade. That combination produces the trap: copy the options table without the plugin's tables, and the plugin reads its stored version, decides it is installed, and queries tables that are not there — forever.
Fix in order of preference:
- Restore the tables from the backup if they held data: orders, form entries, logs you need.
- Trigger the plugin's installer. Deactivating and reactivating runs the activation hook, which is usually enough. If the plugin checks its stored version first, deleting that option makes it reinstall on next load. Find the option name in the plugin's code (
get_option( '…_db_version' )is the usual pattern) rather than guessing. - Use the plugin's own tool. Large plugins ship a "create missing tables" or "database update" action; WooCommerce has Status › Tools, and failures there are their own problem covered in WooCommerce database update not working.
The "made by" stack tells you which plugin is asking, which matters when the table belongs to a different one — a theme or add-on still querying a plugin you removed. Removing a plugin completely means removing the code that depends on it too.
The prefix is wrong
If the missing table has a prefix that differs from $table_prefix, either the prefix was changed — after a security hardening step or an import into a database with different tables — or some code hard-codes wp_ instead of using $wpdb->prefix. In the first case, make wp-config.php and the actual tables agree; changing the prefix — a step some security checklists recommend — involves renaming tables and rewriting a few option and usermeta keys, not just the constant. In the second case, the code is buggy; the stack names the file.
The case is wrong
MySQL on Linux treats table names as case-sensitive by default; on Windows and macOS it does not. A table created as wp_Posts_Stats on a developer's laptop, exported as wp_posts_stats, will not be found on Linux by code that asks for the mixed-case name. Rename the table to match what the code asks for, and fix the code if it is yours.
Common mistakes
- Running the repair screen and expecting a missing table back.
- Recreating an empty table where the backup still has the data.
- Creating the table by hand from a guessed
CREATE TABLE, so the plugin's next schema update fails on a different column. - Silencing
wpdberrors with$wpdb->suppress_errors()and leaving the broken query in place.
Verify
wp db query "SHOW TABLES LIKE 'wp_wc_orders'"(with your table) returns the table.- The page or admin screen that triggered the error loads normally.
tail -f wp-content/debug.logshows no new "doesn't exist" lines over several page loads.- If you recreated a core table,
wp db checkand a quick check of database health show nothing else missing.
Frequently asked
- WordPress writes database errors to the PHP error log unless the code suppressed them, but prints them on the page only when both WP_DEBUG and WP_DEBUG_DISPLAY are true. On a production site with display off, the log is the only place they show up, often thousands of times.
- No. The repair screen enabled by WP_ALLOW_REPAIR runs CHECK TABLE and REPAIR TABLE on tables that exist. It cannot create a table that is gone. Missing core tables are recreated from WordPress's own schema; missing plugin tables are created by the plugin's install routine.
- Either another plugin or the theme still queries the deleted plugin's table, or the plugin was not really removed: its files remain in another location, a must-use loader still includes it, or a scheduled event left behind calls its code. The made by part of the log line names which code is asking.