← Back to blog

How to Read a WordPress Debug Log: Fatal Errors, Warnings and What to Fix First

Learn how to read WordPress debug.log without chasing noise: identify fatal errors, memory exhaustion, plugin/theme paths, repeated warnings and deprecations, then verify the real cause safely.

Code on a monitor illustrating WordPress debug log troubleshooting

A WordPress debug.log is useful only if you can separate the message that explains the failure from the hundreds of lines that happened around it. A log may contain one fatal error, dozens of warnings and thousands of repeated deprecation notices. Reading from the top and fixing every line in order is usually the slowest way to troubleshoot.

This guide explains a practical diagnosis order: reproduce the problem, anchor the investigation to a timestamp, classify the error, identify the execution path, group repeats, and verify the suspected cause with a controlled test. If you already have a log, the free WordPress Debug Log Analyzer can group and classify common entries locally in your browser.

First: understand what WordPress debug logging actually records

WordPress uses WP_DEBUG as the main switch for its debugging mode. The official WordPress documentation explains that WP_DEBUG_LOG can write errors to wp-content/debug.log by default, or to a custom path, while WP_DEBUG_DISPLAY controls whether messages are displayed in generated pages.

A common staging configuration is:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

Put the constants before the “That’s all, stop editing” line in wp-config.php. WordPress explicitly recommends its debugging tools for development/staging rather than normal production use. See the official WordPress debugging documentation for the current behavior and configuration.

Do not start by fixing the first line in the file

A long-running debug log is historical evidence, not a list of current tasks. The first line may be days old. Instead, reproduce the specific problem once and note the time. If checkout failed at 14:32, inspect the entries around 14:32. If saving an Elementor page caused a 500 response, trigger that action once on staging and look at the newest entries.

This gives you a useful correlation: the failure and the log entry happened together. Correlation still does not prove causation, but it is far stronger evidence than an unrelated warning that happened earlier.

Priority 1: PHP fatal errors, parse errors and uncaught exceptions

Start with messages that can terminate execution. Typical patterns include PHP Fatal error, PHP Parse error, Uncaught Error and Uncaught Exception.

A useful fatal entry usually tells you several things:

  • What failed: for example, an undefined function, type error or memory exhaustion.
  • Where PHP reported it: a file path and line number.
  • Which code path was involved: often visible in the stack trace.
  • When it happened: useful for matching the entry to the failed request.

Do not automatically edit the reported line. The line where PHP finally failed may be downstream from the original mistake. A bad value passed by custom code can cause a perfectly valid WooCommerce or WordPress function to throw later.

Memory exhaustion is a symptom and a measurement

An entry containing “Allowed memory size … exhausted” is immediately actionable because PHP could not allocate more memory. It does not automatically mean the correct fix is to keep raising the memory limit.

Ask what the request was doing. Was it importing 20,000 products, generating a large image, running a report, loading an unexpectedly large query result, or looping through data that should have been paginated? A higher limit can be appropriate, but an inefficient loop can consume any reasonable limit.

If you need to generate the correct WordPress/PHP configuration snippets while testing, use the WordPress Memory Limit Generator. Then reproduce the same request and confirm whether memory usage is now reasonable rather than simply assuming the larger number fixed the root cause.

Priority 2: warnings that repeat during the failing request

A PHP warning does not normally terminate execution, but repeated warnings can reveal broken assumptions and can generate substantial log I/O. Examples include undefined array keys, failed file operations and invalid arguments.

Frequency matters. If the same warning appears 800 times during one request, grouping identical messages is much more useful than reading 800 lines. The repetition may indicate a loop, a hook firing more often than expected, or the same bad input reaching a function repeatedly.

The WPToolix analyzer normalizes line numbers and timestamps when grouping common messages, so the same underlying warning is easier to see as one issue with a count.

Priority 3: notices and “doing it wrong” messages

Notices often identify code quality or API-use problems that do not immediately break the request. WordPress also has developer-facing notices when code uses an API incorrectly. These are worth fixing, especially in code you maintain, but do not let them distract you from a fatal error that matches the incident you are investigating.

A good workflow is to resolve the outage or broken action first, then reduce the remaining warning/notice baseline on staging. A quiet log makes future incidents much easier to diagnose.

Deprecation messages are compatibility warnings, not junk

PHP and WordPress deprecation messages tell you that code relies on behavior intended to change or disappear. The PHP manual describes E_DEPRECATED as runtime notices for code that may not work in future versions. WordPress also logs use of deprecated functions and arguments when debugging is enabled.

That makes deprecations especially useful before a PHP or WordPress upgrade. They are often not the immediate cause of a current outage, but a large cluster from one plugin or theme is a reason to check its update status and compatibility before the next platform upgrade. See PHP’s error-level documentation for the current PHP error constants.

How to interpret a plugin or theme path correctly

Suppose a fatal error references:

/wp-content/plugins/example-plugin/includes/class-report.php

That is a strong clue that example-plugin participated in the failing execution path. It is not proof that the plugin itself is defective. The plugin may have received invalid data from custom code, another extension may have called its API incorrectly, or a PHP/WordPress upgrade may have exposed an incompatibility.

The same caution applies to a theme path. Treat paths as a shortlist for investigation, then verify by reproduction, updates, documentation and controlled isolation on staging.

A stack trace is a story of how execution arrived at the failure

When an uncaught error includes a stack trace, read it from the failure outward. The first frames nearest the exception show what was executing when PHP stopped; later frames can reveal the WordPress hook, plugin callback, template or request that led there.

Look for transitions between your own code and third-party code. If a custom plugin calls WooCommerce with an unexpected value and WooCommerce throws a type error, editing WooCommerce core would be the wrong fix. The trace can help identify the boundary where your data entered the failing path.

Database errors need a different question

WordPress database errors can reveal malformed SQL, missing tables/columns, duplicate keys, permission problems or database connectivity issues. WordPress notes that database errors are handled through its wpdb layer and are also affected by debug mode.

When you see one, identify whether the query belongs to WordPress core, a plugin, a theme or custom code. Do not paste production queries containing customer or order data into public forums without redacting sensitive values.

Debug logs can contain sensitive information

This is easy to overlook. Logs can expose server filesystem paths, URLs, email addresses, query fragments, API responses, tokens accidentally written by plugins, and customer-related values. WordPress warns that log files in publicly accessible locations can create a security risk and recommends protecting or removing them after troubleshooting.

That is why the WPToolix analyzer runs client-side: the pasted/uploaded log does not need to be sent to WPToolix for classification. Even so, use care before sharing a report or raw entry with anyone else.

A repeatable troubleshooting workflow

  1. Back up or use staging before changing code/configuration. WordPress recommends a staging environment or appropriate backup before modifications.
  2. Clear or archive an old debug log when safe, so new evidence is easier to isolate.
  3. Reproduce one problem once and note the exact time.
  4. Find fatal/parse/uncaught/memory entries around that time.
  5. Group repeated warnings instead of reading duplicates individually.
  6. Identify plugin/theme/custom-code paths as clues.
  7. Make one controlled change—for example, update the suspected plugin or reproduce with a conflicting extension disabled on staging.
  8. Run the same action again and compare the new log.
  9. Clean up debugging when finished, especially on a public site.

When a debug log is not enough

Logs show recorded events, not the complete runtime state. For difficult performance or database problems, WordPress documents tools such as Query Monitor/Debug Bar, automated tests and Xdebug. Xdebug is useful when you need to stop execution, inspect variables and follow the call stack interactively. SAVEQUERIES can collect query timing information, but WordPress warns that it has a performance impact and should be disabled when you are done.

Use the lightest tool that can answer the question. A log is excellent for “what fatal error happened during this request?” It is less suitable for “why does this function receive the wrong value three calls earlier?”

Analyze the log before changing the site

The safest debugging habit is evidence first, changes second. Start with the exact failed action, isolate the relevant timestamp, rank entries by severity and frequency, and verify the suspected source instead of editing whichever file name appears first.

For a quick first pass, open the WordPress Debug Log Analyzer. It groups repeated entries, classifies common severities, detects memory exhaustion and extracts likely plugin/theme paths—all locally in your browser.

Frequently asked questions

Where is WordPress debug.log stored?

With the standard WP_DEBUG_LOG value of true, WordPress writes to wp-content/debug.log. It can also be configured to use another valid path.

Why is my debug.log empty?

Confirm that WP_DEBUG is actually boolean true, that WP_DEBUG_LOG is enabled, that the file/path is writable, and that you reproduced an action that generates a logged message. WordPress notes that WP_DEBUG_LOG does nothing unless WP_DEBUG is enabled.

Can I leave WP_DEBUG_LOG enabled permanently?

For normal production use, WordPress recommends its debugging tools for development/staging. If you temporarily log on production, protect sensitive logs and disable/remove them when the investigation is complete.

Does a fatal error always identify the plugin that caused it?

No. The reported file is where execution failed. Use the stack trace, timestamp and controlled reproduction to determine the actual cause.