WordPress error logs contain a wealth of diagnostic information, if you know how to read them. A raw log file looks intimidating: cryptic severity labels, absolute file paths, line numbers, and long stack traces that seem to implicate half of WordPress core. Most developers scan it, see nothing immediately obvious, and close it. This guide teaches you to read WordPress error logs systematically: what each severity level means, how to parse a stack trace, what the most common WordPress errors look like and what causes them, and how to configure PHP to log the errors you actually need.
Where WordPress Logs Errors
WordPress errors are written to one of several locations depending on your configuration. The most common location is wp-content/debug.log, which is created when WP_DEBUG_LOG is set to true in wp-config.php. Some server configurations route PHP errors to the server’s system error log instead, typically at /var/log/apache2/error.log on Apache servers or /var/log/nginx/error.log on Nginx. Managed WordPress hosts often have a custom log location accessible from the hosting dashboard.
Finding the Active Error Log
If you are not sure where errors are being logged, check phpinfo() for the error_log directive under the Core section, this shows the file PHP is currently using for error logging. Alternatively, trigger a deliberate PHP notice by adding a temporary line to wp-config.php:
Then check the expected log locations for a new entry with that message. Once you find it, that is your active log file. The complete WP_DEBUG constants guide covers how to configure a custom error log path and route errors away from the default wp-content location.
Anatomy of a WordPress Error Log Entry
Every error log entry follows this format:
Breaking this down:
- Timestamp: When the error occurred, in your server’s local timezone
- Severity label: PHP Notice, PHP Warning, PHP Fatal error, PHP Deprecated, PHP Parse error, or PHP Strict Standards
- Error message: The human-readable description of what went wrong
- File path: The absolute path to the PHP file where the error occurred
- Line number: The exact line within that file
The file path and line number tell you exactly where to look. Open the file in your editor, navigate to that line, and read what is there. The error message tells you what went wrong at that line.
PHP Error Severity Levels Decoded
PHP Fatal Error
A Fatal error stops PHP execution immediately. The script halts at the line where the Fatal error occurred. Any code after that line does not run. On WordPress frontend pages, a fatal error typically produces a white screen (blank page) or HTTP 500 response. In wp-admin, WordPress’s error page displays instead of the admin interface.
Common Fatal error messages and their causes:
- Call to undefined function: A function is called before it is defined, or a plugin that defines the function is not active. Check the call order and plugin dependencies.
- Class not found: A class is instantiated with
new ClassName()but the class definition file has not been loaded. Check autoloader configuration or missingrequire_oncecalls. - Allowed memory size exhausted: PHP reached its memory limit. The process is killed. Increase
memory_limitin php.ini or adddefine('WP_MEMORY_LIMIT', '256M');to wp-config.php. Also investigate what is consuming the memory, an infinite loop, loading too many post objects, or a plugin with a memory leak are the usual suspects. - Maximum execution time exceeded: The request took longer than
max_execution_time. Check for infinite loops, external API calls that do not time out, or large file operations. Increaseset_time_limit()for legitimate long-running operations, or move them to a background WP-Cron task.
PHP Warning
A Warning indicates a non-fatal error that allows script execution to continue, but something went wrong that will likely produce incorrect behavior. Warnings should be treated with the same urgency as Fatal errors, they indicate bugs, not just style issues.
Common PHP Warning messages in WordPress:
- include() failed to open stream: No such file or directory: A theme template, plugin file, or required file does not exist at the specified path. Often caused by hardcoded absolute paths that differ between environments, or missing files in a deployed package.
- array_merge(): Argument #1 is not of type array: A function expects an array but received a different type (null, false, or a scalar). Check what the variable contains at that point, often a function returned false or null instead of an empty array on failure.
- mysql_query() expects parameter 2 to be resource: Legacy code using deprecated mysql_ functions. Should be updated to use $wpdb or PDO.
- Cannot modify header information – headers already sent: Something printed output before WordPress called its header functions. Check for whitespace or BOM characters before the opening
<?phptag in wp-config.php, functions.php, or plugin files.
PHP Notice
A Notice is the least severe PHP error level. Notices indicate that code did something that might be a problem but could also be intentional. The most common Notice in WordPress is accessing an undefined variable or an undefined array index.
- Undefined variable: $varname: A variable is used before it is assigned. In WordPress plugins, this often means a variable expected from a form submission or AJAX request is missing. Fix by checking
isset()before accessing the variable. - Undefined index: keyname: An array is accessed with a key that does not exist. Common in plugins accessing
$_POST,$_GET, or plugin option arrays without checking if the key exists first. - Trying to access array offset on value of type null (PHP 7.4+): Similar to undefined index, a null value is being treated as an array. Check if the function that populated the variable might have returned null.
Despite being “low severity,” notices should be fixed. They often point to race conditions or cases where a request arrives without expected data, conditions that will eventually cause failures in production.
PHP Deprecated
Deprecated notices indicate that code is using a function, method, argument, or feature that has been marked for removal in a future PHP version. These work now but will break when PHP is upgraded. In WordPress contexts, you also see WordPress-specific deprecation notices for functions that WordPress has deprecated (separate from PHP deprecations).
- PHP Deprecated: Function create_function() is deprecated: Uses a PHP function removed in PHP 8.0. Any plugin with this error will crash on PHP 8+.
- PHP Deprecated: Required parameter follows optional parameter: A function signature with optional parameters before required ones, valid in older PHP but deprecated in PHP 8. The function will not work correctly in PHP 8.1+.
- WordPress Deprecated: get_page_by_title is deprecated: A WordPress-level deprecation. The function still works but should be replaced with the recommended alternative.
Deprecated notices are your early warning system for future breakage. When you see a Deprecated notice from a plugin you rely on, check if there is an update available that fixes it, or flag it to the plugin developer. Deprecated calls that are not updated will cause Fatal errors when PHP or WordPress upgrades remove the deprecated feature.
PHP Parse Error (Syntax Error)
A Parse error means PHP could not parse the file due to a syntax error, a missing semicolon, unclosed bracket, mismatched quotes, or invalid syntax. Parse errors cause an immediate white screen because the file cannot be compiled. These are always the developer’s fault (a typo in code) and are easy to locate from the log: the error message includes “syntax error, unexpected token” and the file and line number where the parser failed.
Reading Stack Traces
PHP Fatal errors include a stack trace in the error log, a list of function calls that were in progress when the error occurred. Stack traces read from bottom to top in terms of call origin, and top to bottom in terms of execution order at the moment of the error.
How to Read This
Start at the top: the Fatal error message and the file/line where it crashed. In the example above, the fatal error occurred in /wp-content/plugins/my-plugin/functions.php at line 42. The function that was executing was my_plugin_render().
Move down the stack trace to understand how execution got there. Each #N entry shows one level up the call stack, it shows the function that called the function above it, and the file/line from which it was called. In this example:
#0,my_plugin_render()crashed at line 42 in my-plugin/functions.php#1,my_plugin_render()was called from line 87 of my-plugin/loader.php, by the functionapply_filters()#2, WordPress core’sapply_filters()at wp-includes/class-wp-hook.php called it via the registered hook callback{main}, the bottom of the stack is WordPress’s main bootstrap process
The actionable information is at the top of the trace: the exact file and line where the error occurred, and the immediate calling context. The rest of the stack trace tells you how WordPress triggered the code (through which hook, on which page request), useful context but rarely the place you need to fix.
Common WordPress-Specific Errors
Headers Already Sent
This error means something sent output to the browser before WordPress could set HTTP headers (for redirects, cookies, or HTTP response codes). The most common cause in WordPress: whitespace or BOM characters before the opening <?php tag in wp-config.php, functions.php, or a plugin’s main file. Open each file the error trace references and check the very first bytes, there should be nothing before <?php. Also check for ?> closing tags at the end of PHP files followed by whitespace, standard practice is to omit the closing PHP tag in files that contain only PHP code.
Call to a Member Function on Null
This error means a method was called on a variable that holds null instead of an object. In WordPress, this frequently happens when:
get_queried_object()returns null because no WordPress query matched (404 pages, custom routes)WP_Queryresult is accessed as an object before checking$query->have_posts()- A plugin’s registry or factory method returns null on failure, and the calling code does not check for null before chaining method calls
Fix: always check return values before calling methods on them. Use if ($object instanceof SomeClass) or a null check before calling methods on objects returned by WordPress functions.
Too Few Arguments to Function
This error appears when a callback registered on a WordPress hook is called with fewer arguments than it declares. The common case: a developer registered a callback with add_filter('the_content', 'my_function', 10, 1) but declared function my_function($content, $extra_arg) with two required parameters. WordPress calls it with one argument (the content), and PHP throws this error. Fix: match the number of required function parameters to the $accepted_args parameter of add_filter()/add_action().
Undefined Function wp_enqueue_scripts vs wp_enqueue_script
A subtle but common mistake: confusing the hook name wp_enqueue_scripts (the action hook) with the function name wp_enqueue_script() (the function for enqueuing). Calling wp_enqueue_scripts() as a function name (with an “s”) results in a Fatal “Call to undefined function” error. This type of error is easy to miss in code review because the names look similar.
PHP 8 TypeError on wp_insert_post
PHP 8 introduced strict type checking for internal functions. Many WordPress plugins were written for PHP 7 and pass incorrect types to functions. In PHP 8, passing null where a string is expected now throws a TypeError instead of silently coercing the value. When upgrading to PHP 8, a flood of TypeErrors in the error log is normal, each one identifies code that worked by accident in PHP 7 and needs to be fixed for PHP 8 compatibility.
WordPress-Level Debug Messages
_doing_it_wrong() Notices
WordPress uses _doing_it_wrong() to flag incorrect API usage. These appear in the error log as notices that begin with “WordPress: Function … was called incorrectly.” They are not PHP errors, they are WordPress’s own validation layer. Common examples:
- Widgets need to be registered using register_widget(): A widget is being registered using an approach that WordPress deprecated
- register_rest_route was called incorrectly: The REST route is being registered before the
rest_api_inithook fires - add_theme_support() was called too early: Theme support is being declared before the
after_setup_themehook
_deprecated_function() Notices
WordPress’s deprecation system produces notices like:
The notice always includes the replacement function or alternative. If a plugin’s code triggers this, update the plugin. If it is your own code, switch to the recommended replacement. WordPress maintains backward compatibility for deprecated functions for several major versions before removing them, but “several versions” eventually ends.
error_reporting Levels Explained
PHP’s error_reporting setting controls which types of errors are reported. The value is a bitmask combining the constants for each error type you want to report. Understanding what each level means helps you configure the right logging for each environment.
| Constant | Value | What It Reports |
|---|---|---|
E_ERROR | 1 | Fatal run-time errors. Script stops. |
E_WARNING | 2 | Run-time warnings. Script continues. |
E_PARSE | 4 | Compile-time parse errors. |
E_NOTICE | 8 | Run-time notices (possible bugs). |
E_DEPRECATED | 8192 | Deprecated feature usage. |
E_ALL | 32767 | All errors, warnings, notices, and deprecated. |
E_ALL is what WP_DEBUG = true sets. For production environments where you want errors logged but without the noise of notices, use E_ALL & ~E_NOTICE & ~E_DEPRECATED, this captures Warnings, Fatals, and Parse errors while suppressing the high-volume notice traffic that active sites generate from plugin code.
Filtering the Log: Finding What Matters
On active sites with several plugins, debug.log fills up quickly. A typical WordPress site with WP_DEBUG enabled generates hundreds of notices per day from plugin code that was never fully tested. When you are debugging a specific issue, filter the log to find what matters:
The most useful filter patterns: filter by “PHP Fatal” to find crashes, filter by your plugin’s directory name to find errors from a specific plugin, and filter by a recent timestamp to see only errors from a specific time window.
Custom Error Logging in WordPress
Beyond PHP’s automatic error logging, you can write custom messages to the error log using PHP’s error_log() function or WordPress’s own logging through Query Monitor. Custom logging is useful for debugging values at specific points in code execution, the equivalent of console.log() in JavaScript.
The print_r($variable, true) pattern is essential for logging complex data structures, arrays and objects, to the error log. Without the true argument, print_r echoes directly to the browser instead of returning the string.
Logging to Query Monitor Instead
If Query Monitor is installed (covered in detail in the Query Monitor developer tutorial), you can log custom messages to its panel instead of the error log file. This is more developer-friendly during active development since the output appears in the browser panel with syntax highlighting:
Rotating and Managing debug.log
The wp-content/debug.log file grows without limit if not managed. On production or staging sites with persistent error logging enabled, the file can reach hundreds of megabytes over weeks. Set up log rotation to keep file size manageable and to organize logs by date for easier historical review.
On managed WordPress hosts that do not give you logrotate access, set up a WP-Cron task that truncates debug.log weekly and archives the previous week’s log to a dated file outside the web root. Most managed hosts also expose a “clear logs” button in their control panel, but manually scheduled rotation gives you more control over retention.
Protecting debug.log from Public Access
The default location wp-content/debug.log is within the web root and is publicly accessible if your server configuration does not block it. Error logs contain file paths, database table names, function names, and potentially sensitive data from debug output. Block public access to the log file:
Alternatively, configure a custom log path outside the web root entirely using WP_DEBUG_LOG with a file path as described in the WP_DEBUG constants guide. A log file at /var/log/wordpress/debug.log (outside the public web root) cannot be accessed by web visitors regardless of server configuration.
Diagnosing Intermittent Errors
Some errors appear intermittently, they happen sometimes but not consistently on the same page. These are the hardest to debug because you cannot reliably reproduce them. Strategies for intermittent errors:
- Add timestamps to custom log entries and correlate with your site’s traffic patterns. Errors that happen only during high-traffic periods point to race conditions or resource exhaustion.
- Log the full request context when the error occurs, URL, user ID, POST data, so you can reconstruct the conditions that triggered it.
- Check for PHP-FPM worker exhaustion: When all PHP workers are occupied, new requests queue. If a queued request arrives at a hook too late, values that should be set may be absent. This looks like intermittent undefined variable errors.
- Check for database connection timeouts: Long-running database connections that exceed MySQL’s
wait_timeoutproduce intermittent “MySQL server has gone away” errors. Increasewait_timeoutor implement connection retry logic.
Quick Reference: Error Level to Action
| Error Level | Severity | Script Continues? | Required Action |
|---|---|---|---|
| PHP Fatal | Critical | No | Fix immediately. Site is broken for affected pages. |
| PHP Parse | Critical | No | Fix immediately. File cannot load at all. |
| PHP Warning | High | Yes | Fix this sprint. Likely producing incorrect output. |
| PHP Notice | Medium | Yes | Fix when possible. Often points to real bugs. |
| PHP Deprecated | Medium | Yes | Fix before next PHP upgrade. Will become Fatal then. |
| WP _doing_it_wrong | Low-Medium | Yes | Fix in next update cycle. May break on WordPress upgrades. |
| WP _deprecated_function | Low | Yes | Fix before next WordPress major version. |
Frequently Asked Questions
My debug.log has thousands of identical notices. Is this normal?
It is common but not desirable. High-frequency identical notices indicate a notice-triggering code path that runs on every request (usually in a plugin’s initialization or in a template that loads on every page). Identify the plugin via the file path in the notice, and either update the plugin or add a temporary suppression while you report the issue to the plugin developer. You can reduce log noise by adjusting error_reporting to suppress notices in production while keeping warnings and fatals.
Can I disable error logging for specific plugins?
Not directly at the WordPress level. PHP’s error reporting is global for the process. You can use a custom error handler (set_error_handler()) to filter out errors from specific file paths, but this approach is fragile and can hide real errors. A better approach is to disable WP_DEBUG entirely in production and rely on a staging environment with full debug logging enabled to catch plugin errors before they reach production.
What does “WordPress database error” in the log mean?
WordPress logs database errors when a query fails. The log entry shows the SQL query that failed and the MySQL error message. Common causes: a query references a table that does not exist (missing plugin table after failed installation), incorrect data type passed to a prepared query, or a query exceeds MySQL’s max_allowed_packet size. The MySQL error message in the log entry tells you exactly what MySQL rejected.
WordPress error logs stop being intimidating once you understand the structure. Each entry gives you a timestamp, a severity level, a message, and an exact file and line. Start at the file and line, read the code at that location, and match it against the error message. Fatal errors are the highest priority, fix them first because they break pages. Warnings point to real bugs that need fixing. Notices are opportunities to improve code quality. Deprecated notices are your roadmap for future-proofing. With WP_DEBUG and WP_DEBUG_LOG configured correctly, you always have a clear view of what is going wrong in your WordPress installation.
PHP error logging PHP error types stack trace WordPress Debugging WordPress error handling
Last modified: March 30, 2026