WP Debug Toolkit 1.1.0 is LIVE. Get $300 discount on the lifetime deal now
Use Discount Code WPDTLTD

WordPress has a built-in debug mode that activates PHP error reporting, writes errors to a log file, and optionally displays them in the browser. WP Debug Toolkit (WPDT) gives you toggle switches and WP-CLI commands to control these settings without editing files manually.

If you only remember one thing: WP_DEBUG activates error reporting. WP_DEBUG_LOG writes errors to a file. WP_DEBUG_DISPLAY shows errors in the browser. You almost always want the first two on and the third one off.

Step 1: Understand the debug constants

WordPress debug mode is controlled by three PHP constants defined in wp-config.php. Each one does something different, and they work independently of each other.

WP_DEBUG

define('WP_DEBUG', true);

This is the master switch. When set to true, WordPress tells PHP to report all errors, warnings, notices, and deprecation messages. When set to false (the default), WordPress suppresses most error output.

With WP_DEBUG enabled, you see errors that would otherwise be silently ignored — undefined variables, deprecated function calls, missing arguments, type mismatches. These are not necessarily breaking your site, but they indicate problems that may cause issues later.

WP_DEBUG on its own does not write anything to a file. It only activates error reporting. Where those errors go depends on the next two constants.

WP_DEBUG_LOG

define('WP_DEBUG_LOG', true);

When set to true, WordPress writes all reported errors to a log file at wp-content/debug.log. This is the file you check when something goes wrong.

You can also set WP_DEBUG_LOG to a file path string instead of true:

define('WP_DEBUG_LOG', '/home/user/logs/wordpress-errors.log');

This writes errors to that path instead of the default wp-content/debug.log. Some managed hosts set this automatically to redirect logs to their own location.

WP_DEBUG_LOG requires WP_DEBUG to be true. If WP_DEBUG is false, setting WP_DEBUG_LOG to true has no effect — there are no errors being reported to log.

WP_DEBUG_DISPLAY

define('WP_DEBUG_DISPLAY', false);

The default is true. When you enable WP_DEBUG without explicitly setting WP_DEBUG_DISPLAY to false, errors appear in the browser.

When set to true, PHP errors are printed directly into your site’s HTML output. Visitors see raw error messages in their browser. When set to false, errors are suppressed from the screen but still get logged (if WP_DEBUG_LOG is on).

On a production site, WP_DEBUG_DISPLAY should always be false. Displaying errors to visitors leaks file paths, function names, and database details. It also breaks page layouts when warnings appear in the middle of rendered HTML.

On a local development environment, setting it to true is fine — it lets you see errors inline as you code.

How they work together

WP_DEBUGWP_DEBUG_LOGWP_DEBUG_DISPLAYResult
falseanyanyDebug mode off. Most errors suppressed.
truefalsefalseErrors reported internally but not logged or displayed. Limited use.
truetruefalseErrors logged to file, hidden from visitors. The production setting.
truetruetrueErrors logged to file and shown in browser. The development setting.
truefalsetrueErrors shown in browser but not logged. Risky and not recommended.

Step 2: Enable debug mode manually

This method works on any WordPress site, regardless of what plugins you have installed.

Locate wp-config.php

The file is in your WordPress root directory (the same directory that contains wp-content/, wp-admin/, and wp-includes/). Connect to your server via FTP, SFTP, or SSH, or use your hosting control panel’s file manager.

Add the constants

Open wp-config.php in a text editor. Find the line that reads:

/* That's all, stop editing! Happy publishing. */

Add the following constants above that line:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

If the constants already exist in the file, change their values instead of adding duplicates. Having the same constant defined twice causes a PHP notice and the second definition is ignored.

Save and upload

Save the file and upload it back to the server (if editing via FTP). Reload any page on your site to trigger WordPress to start logging errors.

What happens next

WordPress creates wp-content/debug.log (if it does not already exist) and begins writing error entries to it. The file grows over time as new errors are reported.

A typical log entry looks like this:

[15-Mar-2026 09:21:33 UTC] PHP Warning: Undefined variable $user_name in /wp-content/plugins/example-plugin/includes/class-profile.php on line 84

This tells you: the error type (Warning), what went wrong (undefined variable), the file path, and the line number.

Step 3: Enable debug mode with WPDT

WPDT manages these constants through a UI, so you do not need to edit wp-config.php by hand.

From the WordPress admin dashboard

  1. Go to Debug Toolkit → Overview.
  2. Toggle Error Logging on. This sets both WP_DEBUG and WP_DEBUG_LOG to true.
  3. Leave Error Display off (this keeps WP_DEBUG_DISPLAY set to false).
  4. On a local development environment, toggle Error Display on if you want to see errors in the browser.

WPDT writes the changes to wp-config.php automatically. It creates a backup of the file before making changes.

From the standalone viewer

If WordPress is down or you cannot access the admin dashboard:

  1. Open the standalone viewer URL (e.g., https://example.com/wpdebugtoolkit/).
  2. Press K to open Settings.
  3. Toggle the debug constants from the settings panel.

The viewer writes directly to wp-config.php through its own API — no WordPress required.

From WP-CLI

wp dbtk debug on

This enables WP_DEBUG and WP_DEBUG_LOG. To also enable WP_DEBUG_DISPLAY:

wp dbtk debug on --display

Check the current state:

wp dbtk debug status

Output:

+--------------------+-----------------------------------+
| Setting            | Value                             |
+--------------------+-----------------------------------+
| WP_DEBUG           | ON                                |
| WP_DEBUG_LOG       | ON                                |
| WP_DEBUG_DISPLAY   | OFF                               |
| SAVEQUERIES        | OFF                               |
| Enhanced logging   | OFF                               |
| Log path           | /var/www/html/wp-content/debug.log|
+--------------------+-----------------------------------+

Step 4: Verify it works

After enabling debug mode, confirm that errors are being logged.

Check that debug.log exists

Look for wp-content/debug.log on the server. If the file does not exist yet, no errors have been reported since you enabled debug mode.

Trigger a test error

On a staging or development site, you can force an error to confirm logging works. Add this line temporarily to your theme’s functions.php:

error_log('WPDT test: debug logging is working');

Reload the site, then check debug.log. You should see an entry like:

[15-Mar-2026 09:25:00 UTC] WPDT test: debug logging is working

Remove the test line after confirming.

Use WPDT to verify

In the standalone viewer, navigate to Error Logs. If logging is working, you see entries appearing. If the log is empty, the test error above confirms whether the logging pipeline is connected.

Step 5: Production vs development settings

The right debug configuration depends on where the site is running.

Production sites

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Log errors to a file. Never show them to visitors. This gives you a record of problems without exposing server details to the public.

Some developers set WP_DEBUG to false on production. This means you get no error logging at all — problems happen silently and you find out when a client reports a broken page. Keeping WP_DEBUG and WP_DEBUG_LOG on while keeping WP_DEBUG_DISPLAY off is the safer approach.

Development and staging sites

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', true);

Show errors directly in the browser so you catch problems as you work. Also log to file so you have a record.

Local development

Same as staging, but you can also enable SCRIPT_DEBUG and SAVEQUERIES for deeper insight:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', true);
define('SCRIPT_DEBUG', true);
define('SAVEQUERIES', true);

SCRIPT_DEBUG loads unminified versions of core CSS and JS files. SAVEQUERIES stores all database queries in memory for analysis (see How to Find Slow Database Queries).

Step 6: Disable debug mode when done

If you enabled debug mode for a specific troubleshooting session, disable it when you are finished.

Manual method

Open wp-config.php and change:

define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);

Or remove the lines entirely. WordPress defaults to false for all three when they are not defined.

WPDT method

Toggle the switches off in Debug Toolkit → Overview, or run:

wp dbtk debug off

Should you leave debug mode on permanently?

On production, keeping WP_DEBUG and WP_DEBUG_LOG on with WP_DEBUG_DISPLAY off is a reasonable permanent configuration. The performance impact is minimal, and you always have a log to check when problems arise.

The risk of leaving it on is that debug.log grows over time. If you leave it on, set up log rotation or use WPDT’s automatic log cleanup to manage file size.

Troubleshooting

Constants are defined twice

If wp-config.php contains two definitions for the same constant, PHP uses the first one and ignores the second. You see a notice like:

PHP Notice: Constant WP_DEBUG already defined in /wp-config.php on line 92

Search the file for duplicate define('WP_DEBUG' lines. Remove the duplicate. Some hosting panels or security plugins add their own definitions — check the entire file.

Constants placed after “stop editing”

The /* That's all, stop editing! */ comment is followed by code that loads WordPress. Constants defined after this line may not take effect because WordPress has already initialized.

Move your define() statements above that comment.

Confusing WP_DEBUG_LOG with WP_DEBUG_DISPLAY

WP_DEBUG_LOG writes to a file. WP_DEBUG_DISPLAY shows in the browser. These are independent settings. Enabling WP_DEBUG_LOG does not show anything on screen. Enabling WP_DEBUG_DISPLAY does not write to a file.

If you want both, set both to true. If you want logging without browser output (the production setup), set WP_DEBUG_LOG to true and WP_DEBUG_DISPLAY to false.

Nothing appears in the log

Check these in order:

  1. Is WP_DEBUG set to true? Without this, nothing is reported.
  2. Is WP_DEBUG_LOG set to true? Without this, reported errors are not written to a file.
  3. Is the wp-content/ directory writable by PHP? Check file permissions — the directory needs to be writable (typically 0755) for WordPress to create debug.log.
  4. Is another plugin or host configuration overriding error handling? Some security or performance plugins suppress error output. Some managed hosts redirect PHP errors to their own log system.
  5. Are there actually errors? If your site is running cleanly, the log is empty. Trigger a test error (see Step 4) to verify the pipeline works.

Errors showing on the live site

WP_DEBUG_DISPLAY is set to true. Change it to false:

define('WP_DEBUG_DISPLAY', false);

If you changed it but errors still show, check for a second definition of WP_DEBUG_DISPLAY later in the file. Also check whether a plugin is calling ini_set('display_errors', '1') — this overrides the constant.

You can also force display off at the PHP level by adding this to wp-config.php:

@ini_set('display_errors', 0);

File permissions prevent logging

WordPress needs write access to the wp-content/ directory (or whatever directory the log file lives in). If PHP cannot write to the directory, no log file is created and no errors are logged.

Check permissions:

ls -la wp-content/

The directory should be owned by the web server user (often www-data on Linux) or your hosting account user, with permissions 0755. The debug.log file, once created, should have permissions 0644.

If you are on shared hosting without shell access, use your hosting panel’s file manager to check and fix permissions.

wp-config.php is read-only

Some hosting environments (Flywheel, certain managed hosts) make wp-config.php read-only. In this case, WPDT attempts automatic permission elevation — temporarily making the file writable, writing the change, and restoring the original permissions. If that fails, you need to edit the file through your host’s control panel or contact support.

Advanced topics

Custom log paths

Instead of the default wp-content/debug.log, you can write errors to any path by setting WP_DEBUG_LOG to a string:

define('WP_DEBUG_LOG', '/home/user/logs/wordpress-debug.log');

This is useful when:

  • Your host puts logs in a non-standard location
  • You want the log outside the web root (so it cannot be downloaded via a direct URL)
  • You are running multiple WordPress sites and want separate log files

WPDT supports custom paths. Set the path in Settings → File Paths or define the DBTK_LOG_PATH constant. See Custom Log Paths for details.

SCRIPT_DEBUG

define('SCRIPT_DEBUG', true);

This constant tells WordPress to load the original, unminified versions of core JavaScript and CSS files instead of the minified versions. It is useful when you are debugging JavaScript errors that reference line numbers in minified files — the unminified versions have readable variable names and meaningful line numbers.

SCRIPT_DEBUG has no effect on plugin or theme files unless those plugins/themes explicitly check for it.

WP_DISABLE_FATAL_ERROR_HANDLER

define('WP_DISABLE_FATAL_ERROR_HANDLER', true);

Since WordPress 5.2, fatal errors are caught by a built-in fatal error handler. Instead of a blank white screen, WordPress shows a “There has been a critical error” message and sends a recovery email to the admin.

Setting WP_DISABLE_FATAL_ERROR_HANDLER to true disables this handler. Fatal errors produce the classic white screen (or PHP’s default error output if display_errors is on). This is sometimes useful during development if the recovery mode handler is interfering with your debugging workflow, but it should not be enabled on production.

CONCATENATE_SCRIPTS

define('CONCATENATE_SCRIPTS', false);

WordPress concatenates admin scripts into fewer HTTP requests by default. Setting this to false loads each script individually, which makes it easier to identify which script is causing a JavaScript error. This is an admin-only setting and has no effect on the frontend.

SAVEQUERIES

define('SAVEQUERIES', true);

This stores every database query WordPress runs during a page load, along with the execution time and a backtrace of the calling code. The data is stored in $wpdb->queries and can be dumped for analysis.

Do not leave SAVEQUERIES enabled on production — it consumes significant memory on complex pages. Use it for targeted debugging sessions or use WPDT’s Database Monitor for a more practical approach. See How to Find Slow Database Queries.

Summary

Manual (wp-config.php)WPDT (UI/CLI)
How to enableEdit file, add define() linesToggle switch or wp dbtk debug on
How to disableEdit file, change values to falseToggle switch or wp dbtk debug off
Backup before changesYou handle itAutomatic backup
Works without wp-adminYes (via FTP/SSH)Yes (via standalone viewer or WP-CLI)
Works without WordPressYes (editing a PHP file)Viewer: yes. Admin UI: no.
Risk of typosYes (editing PHP by hand)No (UI writes the constants)
GridPane compatibilityManual: edit secure-debug.phpAutomatic detection and handling
Hosting with read-only wp-configManual: contact hostAutomatic permission elevation (when possible)
On this page
Try WP Debug Toolkit
The best error log viewer with amazing developer tools to help you troubleshoot your WordPress site securely and efficiently. Something something more.