Skip to content

Search WPDesignVault

Try "image", "json", "schema" or "contrast". Use arrow keys to move through results.

WordPress

Using WP_DEBUG Safely on a Live Site

The safe WP_DEBUG setup for live sites, with test results showing what visitors see under each setting, how to read the log and how to handle fatal errors.

Comprehensive guide and visual tutorial explaining wp_debug for WordPress websites.
On this page

To use WP_DEBUG safely on a live site, turn it on with error display switched off and logging switched on. Write the log to a file outside the public web folder, reproduce the problem, read the log, then turn debugging off again. The safe combination is WP_DEBUG true, WP_DEBUG_DISPLAY false and WP_DEBUG_LOG set to a private file path. Never switch on WP_DEBUG by itself. WordPress shows errors on screen by default when debugging is on. Visitors see them, they reveal file paths, and they can break JSON responses that forms and the block editor rely on.

This post explains what each debugging constant does and gives a step-by-step routine for a live site. It also covers how to read the log and what to do about fatal errors. Every scenario in it was tested on a WordPress 7.1.3 test site, using a small plugin that deliberately triggered a warning and a fatal error. The results show exactly what visitors would see with each setting.

What the debugging constants do

Table: WordPress debugging constants (defaults from WordPress core)

Constant Default Effect when set
WP_DEBUG false true makes PHP report all errors, warnings and notices
WP_DEBUG_DISPLAY true Controls whether errors are printed on the page while WP_DEBUG is on
WP_DEBUG_LOG false true writes to wp-content/debug.log; a file path writes to that file instead
SCRIPT_DEBUG false Loads unminified core CSS and JavaScript, for front-end debugging
WP_DISABLE_FATAL_ERROR_HANDLER Not set true turns off WordPress's "critical error" handler and recovery mode

The trap is in the second row. Because WP_DEBUG_DISPLAY defaults to true, adding only define( 'WP_DEBUG', true ); prints every warning into your pages.

<h2
Step-by-step workflow architecture diagram for implementing wp_debug on live sites.
Three-phase workflow architecture diagram for generating, deploying, and testing wp_debug.

What we saw on the test site

We added a small must-use plugin that triggered a PHP warning (reading a missing array key) on a front-end page and in a REST API request, and a fatal error (calling an undefined function) on request. Then we tried each configuration. The server's own PHP setting had display_errors off, as most production hosts do.

Table: Results by configuration (WordPress 7.1.3 test site)

Configuration Warning shown to visitors? REST API response Logged?
A: WP_DEBUG false (default) No Valid JSON No
B: WP_DEBUG true only Yes, with the full server file path Broken: warning HTML printed before the JSON No
C: plus WP_DEBUG_LOG true and WP_DEBUG_DISPLAY false No Valid JSON Yes, in wp-content/debug.log
D: as C, but WP_DEBUG_LOG set to a private path No Valid JSON Yes, in the private file

Configuration B is what many quick tutorials suggest. On our test site, it printed a warning naming the plugin file's full path on the server, and it put that warning in front of the REST API's JSON output, which made the response unreadable as JSON. Requests sent with an Accept: application/json header stayed valid, because WordPress turns display off for requests it recognises as JSON. Many requests from themes and plugins do not send that header. The block editor, forms and AJAX features can fail in confusing ways while display is on.

For fatal errors, WordPress's error handler showed the generic message "There has been a critical error on this website" with status 500 in both B and C. In B, the PHP fatal error details were printed on the page as well. In C and D, visitors saw only the generic message, and the details went to the log.

Before you start

  • Back up wp-config.php so you can restore it if you make a typing mistake.
  • Use staging if you can. Reproduce the problem on a copy of the site first. Debug live only when the problem appears only there.
  • Find a private folder for the log, outside the public web root, such as a logs folder in your hosting account's home directory. Your host's file manager shows the full path.
  • Know how to reproduce the problem: the page, the button or the time it happens.
  • Plan to turn debugging off as soon as you have what you need.
<h2
Recommended best practices checklist and common pitfalls to avoid for wp_debug Tested for WordPress.
Implementation checklist comparing recommended best practices against common errors in wp_debug.

Step by step: debug a live site safely

  • Open wp-config.php and find the line define( 'WP_DEBUG', false );.
  • Replace it with this block (above the "stop editing" line), using your own private path:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/home/account/logs/wp-debug.log' );
define( 'WP_DEBUG_DISPLAY', false );

Then work through the rest of the routine:

  • Check: save the file, load a page and confirm no errors appear on screen.
  • Reproduce: repeat the action that causes the problem.
  • Read: download the log file and find the entries with matching times.
  • Switch off: when you have what you need, set WP_DEBUG back to false and delete the log, or move it to a private archive.

Edit the existing WP_DEBUG line rather than adding a second one. If a constant is defined twice, PHP keeps the first value and ignores yours. Our guide to wp-config.php settings covers where custom lines go and other editing mistakes.

If you have to use the default log location

Some hosts do not let PHP write outside the web root. If you set WP_DEBUG_LOG to true, the log goes to wp-content/debug.log, inside the public web folder. On a plain Apache server we tested for our wp-config guide, that file downloaded with status 200 until it was blocked. Block it before you start:

# Apache: wp-content/.htaccess
<Files "debug.log">
  Require all denied
</Files>
# Nginx: inside the server block
location = /wp-content/debug.log { deny all; }

Then confirm with the HTTP status checker that /wp-content/debug.log returns 403 or 404, not 200. Our guide to the default WordPress .htaccess file explains where Apache rules go.

Reading the log

Each line has a timestamp, a severity and a message with a file and line number. An illustrative entry:

[14-Oct-2026 12:41:07 UTC] PHP Warning:  Undefined array key "missing_key" in /home/account/public_html/wp-content/plugins/example-plugin/includes/cart.php on line 88

Table: Severity levels you will see

Level Meaning Urgency
Fatal error PHP stopped; the page failed Fix now
Warning Something went wrong but the page continued Investigate
Notice A minor problem, often harmless Low, unless repeated constantly
Deprecated Code uses a feature that will be removed in a future PHP or WordPress version Plan an update

The file path tells you where the problem is. A path containing /plugins/example-plugin/ points to that plugin, /themes/ to a theme, and /wp-includes/ or /wp-admin/ usually to a plugin or theme calling core incorrectly rather than a core bug.

Worked example: tracking down a broken checkout button

An illustrative shop reports that "Place order" sometimes spins and never finishes.

  • The developer enables configuration D with a private log path.
  • They place a test order and watch the browser's Network panel. The checkout request returns a response that starts with HTML instead of JSON.
  • The log shows a warning from a shipping plugin's file on each checkout, at the same second as the failed request.
  • On staging, they update the shipping plugin, and the warning disappears.
  • They apply the update on live, confirm a test order works, then set WP_DEBUG back to false and delete the log.

In this case, someone had earlier left WP_DEBUG on with display enabled. The printed warning was corrupting the JSON response, which is exactly the failure our test reproduced with the REST API.

Fatal errors and recovery mode

Since WordPress 5.2, a fatal error caused by a plugin or theme shows visitors a generic "critical error" message rather than a white screen. WordPress also tries to email the site administrator a link to recovery mode, which lets an administrator log in with the faulty plugin or theme paused. If you do not get the email, check the admin email address in Settings → General and your site's mail delivery.

Leave the fatal error handler on for live sites. WP_DISABLE_FATAL_ERROR_HANDLER is meant for development environments where you want raw errors.

Keeping debugging tidy

  • Set an end time. Debug for the shortest time that captures the problem.
  • Watch log size. A busy site with a noisy plugin can write a very large log quickly.
  • Do not share raw logs publicly. They can contain file paths, plugin names, usernames and request data. Trim them before posting in support forums.
  • Mark environments. Set WP_ENVIRONMENT_TYPE to staging on staging so plugins can behave accordingly, and keep debug display on there only.

Verify debugging is safely off afterwards

  • Open wp-config.php and confirm WP_DEBUG is false, or the debug block is removed.
  • Check Tools → Site Health → Info → WordPress Constants, which lists the values WordPress is using.
  • Request the old log location in a browser and confirm it is not downloadable.
  • Delete or archive the log file.

If you are setting up a site from scratch, the wp-config.php generator lets you choose debug logging and keeps on-screen errors as a separate, development-only option.

Common mistakes

  • Adding only define( 'WP_DEBUG', true ); on a live site.
  • Leaving debugging on for weeks and filling the disk with logs.
  • Logging to wp-content/debug.log without blocking public access.
  • Adding a second WP_DEBUG line below the original one, which PHP ignores.
  • Putting the debug block after the require_once ABSPATH . 'wp-settings.php'; line, where it is too late.
  • Pasting raw logs into public support threads.
  • Disabling the fatal error handler on production.

Troubleshooting

Table: WP_DEBUG problems and fixes

Symptom Likely cause Fix
Errors visible on the site WP_DEBUG_DISPLAY not set to false Add define( 'WP_DEBUG_DISPLAY', false );
No log file appears WP_DEBUG is false, the folder is not writable, a duplicate constant, or no errors yet Check each; reproduce the problem
Block editor or forms fail after enabling debug Warnings printed into JSON responses Turn display off
Log grows very quickly A notice or deprecation repeated on every request Fix or update the source; turn debugging off after capture
"There has been a critical error" message A fatal error Read the log; use the recovery mode email to log in
Changes to wp-config.php seem ignored for a moment PHP OPcache serving the old file Wait a few seconds, or clear OPcache in your host's panel

Frequently asked questions

Is it safe to turn on WP_DEBUG on a live site?

Only with display off and logging on. WP_DEBUG alone prints errors to visitors, and in our test it exposed a file path and broke REST API responses.

Where is the WordPress debug log?

In wp-content/debug.log if WP_DEBUG_LOG is true, or at the path you give it if you set WP_DEBUG_LOG to a file path.

Why is WP_DEBUG_DISPLAY important?

It defaults to true, so with WP_DEBUG on, errors appear in pages unless you set it to false.

Can I change where the debug log is saved?

Yes. Set WP_DEBUG_LOG to a full file path, ideally outside the public web folder. WordPress core supports a path as well as true or false.

Why is my debug.log empty or missing?

Debugging may be off, the constant may be defined twice, the folder may not be writable, or no errors have happened since you turned it on.

Does WP_DEBUG slow down a site?

Logging adds a little work, and very noisy logs can add more. That is one reason to turn debugging off when you have finished.

What is SCRIPT_DEBUG?

It makes WordPress load unminified core CSS and JavaScript, which helps debug front-end problems. Turn it off afterwards so visitors get the smaller files.

What is WordPress recovery mode?

When a plugin or theme causes a fatal error, WordPress emails the administrator a link that pauses the faulty extension so you can log in and fix it.

Should I disable the fatal error handler?

Not on a live site. It hides technical details from visitors and enables recovery mode. Disable it only in development.

Can I share my debug log in a support forum?

Share only the relevant lines, and remove file paths, usernames and request data first. Full logs can expose information about your server.

Next step

Add the three-line safe debugging block to wp-config.php with a private log path, reproduce your problem, and set WP_DEBUG back to false as soon as you have the log lines you need. For related configuration and server topics, browse our WordPress guides.

wp-config.php Generator

Generate a complete wp-config.php with database details, newly generated security keys, debug settings and useful constants. Keys are…

WordPress Snippet Generator

Generate clean, escaped WordPress code for the tasks developers repeat most: enqueueing scripts and styles, shortcodes, widget areas,…

Custom Taxonomy Generator

Generate clean, translation-ready register_taxonomy() code for WordPress, with category-style or tag-style behaviour, block editor support and admin columns.

301 Redirect Generator

Paste old and new URLs to generate exact-match redirect rules for Apache (.htaccess), Nginx or a WordPress snippet.…

Related articles

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *