"There Has Been a Critical Error on This Website": How to Debug It
What WordPress does when it shows the critical error message, how to use the recovery mode email, how to read a fatal error and its stack trace, and which fix belongs to which error.

A WordPress critical error is a PHP fatal error that WordPress caught before it could leave visitors with a blank page. The screen says only "There has been a critical error on this website", but the exact cause is written down in two places: an email to the site administrator and the PHP error log. The job is to get that text, read it properly, and act on the file it names.
Getting and reading that text needs no programming. What you do next depends on what it says.
What WordPress does when PHP hits a fatal error
A fatal error is one PHP cannot continue from: a call to a function that does not exist, a syntax mistake, a wrong type of value, memory running out. WordPress registers a handler for these. When one occurs, the handler sends the visitor the short message with an HTTP 500 status and works out whether the failing file belongs to a plugin or a theme. If it does, and the request was for the login screen or the dashboard, WordPress emails the site's administration address. The subject is "Your Site is Experiencing a Technical Issue", and the body names the plugin or theme, quotes the error and carries a private link into recovery mode.
Three details explain most of the confusion around this email:
- It is sent at most once a day by default. A second error the same afternoon produces no second message, so search the inbox for an earlier one.
- It is triggered by errors on the login screen and in the dashboard, not on public pages. If only the front end is broken, the dashboard still works and you do not need recovery mode at all.
- It covers regular plugins and themes. An error in a must-use plugin, a drop-in such as
object-cache.php, orwp-config.phpshows the same message to visitors and sends nothing.
The design is described in the core team's note on fatal error recovery mode.
Start with the recovery mode email
- Find the email. It goes to the address under Settings > General > Administration Email Address, which on many sites still belongs to whoever built the site. Check the spam folder too.
- Read it before you click. The plugin or theme name and the "Error Details" block at the bottom are the diagnosis. Copy them somewhere.
- Open the link and log in as an administrator. By default the link works for one day.
- Go to the Plugins screen (or Appearance > Themes). The extension that failed is marked as paused, with the error shown beneath it.
- Deactivate it, or fix the cause and choose "Resume".
- Click "Exit Recovery Mode" in the admin bar and check the site in a private window.
Recovery mode pauses the broken extension for your browser session only. Visitors keep seeing the error until you deactivate or repair it.
If the email never arrives, the site may be unable to send mail at all (see why WordPress email fails and how to fix it). You can point the message at a different inbox with define( 'RECOVERY_MODE_EMAIL', 'you@example.com' ); in wp-config.php. Either way, the log holds the same information.
Get the error from the log when there is no email
Switch on the debug log, load the failing page once, and read the last entries. Over SSH with WP-CLI, three commands write the settings into wp-config.php for you:
wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY false --raw
tail -n 40 wp-content/debug.log
Without SSH, add the same three constants by hand above the line that loads wp-settings.php, then download wp-content/debug.log. If the file stays empty, read the PHP error log in the hosting control panel, which records the same error. Turn WP_DEBUG off again when you have what you need. The wp config command reference lists the options.
Read the fatal error and its stack trace
A typical entry looks like this, with a made-up plugin name:
PHP Fatal error: Uncaught Error: Call to undefined function wc_get_order() in /home/site/public_html/wp-content/plugins/example-labels/includes/class-label.php:84
Stack trace:
#0 /home/site/public_html/wp-includes/class-wp-hook.php(324): Example_Label->render()
#1 /home/site/public_html/wp-includes/plugin.php(517): WP_Hook->do_action()
#2 /home/site/public_html/wp-admin/admin.php(175): do_action()
#3 {main}
thrown in /home/site/public_html/wp-content/plugins/example-labels/includes/class-label.php on line 84
Read it in four parts.
- The message, after "Uncaught Error": what went wrong. Here the code called
wc_get_order()and no such function was loaded. - The location, after "in": the file, then the line number after the colon. This is where PHP gave up.
- The stack trace: the chain of calls that led there, nearest first. Lines inside
wp-includesandwp-adminare WordPress passing the call along and are almost never at fault. Look for the first path underwp-content. - "thrown in": the location once more.
The file where the error surfaces is not always the root cause. Here the labels plugin calls a WooCommerce function, so the real question is why WooCommerce is not loaded.
Which plugin or theme the path belongs to
| The path contains | It belongs to | What you can do |
|---|---|---|
wp-content/plugins/name/ | The plugin in the folder "name" | Deactivate, update or roll back that plugin |
wp-content/themes/name/ | The theme or child theme | Restore the edited file, or switch theme |
wp-content/mu-plugins/ | A must-use plugin, often added by the host or a developer | Rename the file over SFTP and ask who installed it |
wp-content/object-cache.php and similar | A drop-in created by a caching plugin | Rename the file, then reinstall that plugin |
Only wp-includes/ or wp-admin/ | WordPress core | Read further down the trace, then verify the core files |
The folder name is the plugin's slug, which can differ from the name shown in the dashboard. If you cannot match it, the "Plugin Name" line at the top of the main PHP file in that folder settles it.
Fixes for the errors you will meet most
Back up the files and the database before you deactivate, update or roll back anything on a live site. A plugin that changes its own database tables during an update cannot always be undone by uploading the old files.
Call to undefined function, or class not found
The code depends on something that is not there. An add-on is active while its parent plugin is not, the two are on versions that no longer match, a PHP extension is missing, or the code uses a function that newer PHP versions removed, such as each() or create_function(). Activate or update the missing piece, or bring both plugins to versions that belong together.
Cannot redeclare a function or class
The same name is defined twice. Look for two copies of one plugin in wp-content/plugins (a manual upload can leave a second folder with a suffix), or a snippet in functions.php that duplicates something a plugin now provides. Delete the duplicate.
Syntax error, unexpected something
PHP could not read the file as code. Either someone edited it and left out a bracket or semicolon, in which case restore the previous copy, or the plugin uses syntax newer than the server's PHP version, in which case compare the "Requires PHP" line on the plugin's page with what your host runs.
TypeError, ValueError or ArgumentCountError
These usually appear right after a PHP upgrade. PHP 8 stops on mismatched types that older versions only warned about. Update the plugin first. If it is abandoned, replace it, patch it, or move PHP back one version for a short time while you decide.
Allowed memory size exhausted, or maximum execution time exceeded
A resource limit was reached. The file in the message is where the limit ran out, which is not necessarily the code that used it up.
Deciding who should fix a WordPress critical error
If the trace names a third-party plugin or theme and deactivating, updating or rolling it back clears the error, you can finish this alone. Send the full log entry to the plugin's support forum so the author can fix it for everyone. Our guide to rolling back a WordPress update covers the safe way to return to an earlier version.
Get help when the file in the trace is custom code nobody on your team wrote, when the failing plugin runs payments, enrollments or bookings and cannot stay off, or when a new fatal error follows every WordPress or PHP update. That last pattern means the site carries code nobody maintains. Finding and replacing it is routine work for a WordPress maintenance team, and where a plugin has to be rewritten, for plugin developers who will keep it current.
Frequently asked questions
Does a critical error mean the site was hacked?
Rarely. It is nearly always a compatibility problem after an update, a PHP version change or a manual edit. Be suspicious only when the trace names files you do not recognize, such as PHP files inside wp-content/uploads, or core files that changed without an update.
How long does the recovery mode link work?
One day by default. After it expires, WordPress sends a fresh link the next time the error occurs on the login screen or in the dashboard. The link gives access to the login form only, so you still need an administrator account.
Can I switch the critical error screen off?
Yes, with define( 'WP_DISABLE_FATAL_ERROR_HANDLER', true ); in wp-config.php. That disables the handler and recovery mode together, and visitors get a blank page or a raw PHP error in its place. Keep it to staging copies.
The error names a plugin I cannot run the site without. What now?
Roll that plugin back to the version that worked, using the previous releases listed on its WordPress.org page or in your account with the vendor. Then test the newer version on staging and report the error to the author.
Add worldwincoder.com as a preferred source on Google, or open this article in your AI assistant to use it as a source.
