Introduction

WordPress critical errors occur when the CMS cannot load properly due to PHP fatal errors, database connection failures, plugin/theme conflicts, or resource exhaustion. The most common manifestation is the "White Screen of Death" (WSOD) where the site displays a blank white page with no error message. Other critical errors include "Error Establishing a Database Connection", "The Site Is Experiencing Technical Difficulties", critical error emails from WordPress, admin dashboard inaccessible, and fatal errors from memory exhaustion. Common causes include plugin conflicts after updates, theme functions.php syntax errors, WordPress core update failures, database corruption, PHP version incompatibility, memory limit exhaustion, file permission issues, corrupted wp-config.php, and object cache backend failures. The fix requires systematic debugging, enabling error display, checking logs, and isolation techniques. This guide provides production-proven troubleshooting for WordPress critical errors across shared hosting, VPS, and managed WordPress environments.

Symptoms

  • White screen with no content (White Screen of Death)
  • Error Establishing a Database Connection
  • The site is experiencing technical difficulties
  • There has been a critical error on this website
  • WordPress admin (/wp-admin) inaccessible
  • Critical error email received from WordPress
  • Fatal error: Allowed memory size exhausted
  • Fatal error: Uncaught Error: Call to undefined function
  • Warning: Cannot modify header information - headers already sent
  • Error: There was a critical error with this plugin
  • Site partially loads but CSS/images missing
  • Login page refreshes without error

Common Causes

  • Plugin update introduced PHP fatal error or conflict
  • Theme update broke compatibility with WordPress version
  • WordPress core update failed mid-installation
  • Database credentials changed or database server down
  • PHP version upgraded beyond plugin/theme compatibility
  • Memory limit too low for WordPress + plugins
  • File permissions incorrect after migration/backup restore
  • wp-config.php corrupted or missing required constants
  • Object cache (Redis/Memcached) connection failed
  • Database tables corrupted or crashed
  • .htaccess file corrupted causing rewrite failures
  • PHP extension missing (mysqli, curl, gd, etc.)

Step-by-Step Fix

### 1. Enable WordPress debugging

Enable debug mode:

```php // wp-config.php - Add or modify these lines

// Enable WP_DEBUG mode define( 'WP_DEBUG', true );

// Enable Debug logging to /wp-content/debug.log define( 'WP_DEBUG_LOG', true );

// Disable display of errors on frontend (production safe) define( 'WP_DEBUG_DISPLAY', false ); @ini_set( 'display_errors', 0 );

// Enable script debugging define( 'SCRIPT_DEBUG', true );

// Save database queries for debugging define( 'SAVEQUERIES', true );

// Enable autosave debugging define( 'AUTOSAVE_INTERVAL', 300 ); ```

Check debug log:

```bash # After enabling debug, check the log file tail -f wp-content/debug.log

# Common error patterns:

# Memory exhausted # PHP Fatal error: Allowed memory size of 268435456 bytes exhausted

# Plugin conflict # PHP Fatal error: Uncaught Error: Call to undefined function in /wp-content/plugins/plugin-name/file.php

# Theme error # PHP Fatal error: Cannot redeclare function_name() in /wp-content/themes/theme-name/functions.php

# Database error # WordPress database error Table './wp_posts' is marked as crashed

# Missing PHP extension # PHP Fatal error: Uncaught Error: Call to undefined function mysqli_connect() ```

Enable error display temporarily (development only):

```php // wp-config.php - Development only! define( 'WP_DEBUG', true ); define( 'WP_DEBUG_DISPLAY', true );

// Or add to .htaccess (Apache) php_value display_errors On php_value display_startup_errors On

# NEVER use in production - exposes sensitive information ```

### 2. Fix White Screen of Death

Disable plugins via filesystem:

```bash # Method 1: Rename plugins folder (disables all plugins) cd wp-content mv plugins plugins.disabled mkdir plugins

# Access site - if it loads, problem is plugin-related # Restore plugins folder name mv plugins.disabled plugins

# Method 2: Deactivate plugins via database mysql -u username -p database_name

# Deactivate all plugins UPDATE wp_options SET option_value = '' WHERE option_name = 'active_plugins';

# Or via WP-CLI wp plugin deactivate --all

# Method 3: Access via FTP/SFTP # Rename individual plugin folders in wp-content/plugins/ # Start with recently updated plugins ```

Identify problematic plugin:

```bash # Systematic plugin isolation

# 1. Deactivate all plugins wp plugin deactivate --all

# 2. Check if site loads curl https://example.com | head -20

# 3. Reactivate plugins one by one wp plugin activate akismet curl https://example.com | head -20

wp plugin activate jetpack curl https://example.com | head -20

# When site breaks, last activated plugin is culprit

# Alternative: Check error log after each activation tail -n 50 wp-content/debug.log ```

Switch to default theme:

```bash # Method 1: Via WP-CLI wp theme activate twentytwentyfour

# Method 2: Via database mysql -u username -p database_name UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'template'; UPDATE wp_options SET option_value = 'twentytwentyfour' WHERE option_name = 'stylesheet';

# Method 3: Via filesystem # Rename current theme folder to force fallback cd wp-content/themes mv current-theme current-theme.disabled

# WordPress will fall back to default theme ```

### 3. Fix database connection errors

Diagnose database issues:

```bash # Test database connection manually mysql -u db_username -p -h db_host db_name

# Common errors: # ERROR 2002 (HY000): Can't connect to local MySQL server through socket # -> MySQL not running or wrong socket

# ERROR 1045 (28000): Access denied for user # -> Wrong username/password

# ERROR 1049 (42000): Unknown database # -> Database doesn't exist

# Check MySQL service systemctl status mysql # Or systemctl status mariadb

# Check WordPress database config cat wp-config.php | grep -E "DB_NAME|DB_USER|DB_PASSWORD|DB_HOST"

# Output: # define( 'DB_NAME', 'wordpress_db' ); # define( 'DB_USER', 'wp_user' ); # define( 'DB_PASSWORD', 'secret_password' ); # define( 'DB_HOST', 'localhost' ); ```

Fix database credentials:

```php // wp-config.php - Verify credentials match database

define( 'DB_NAME', 'correct_database_name' ); define( 'DB_USER', 'correct_username' ); define( 'DB_PASSWORD', 'correct_password' ); define( 'DB_HOST', 'localhost' ); // Or IP/hostname for remote DB

// For managed hosting, check hosting panel for correct values // For Amazon RDS: endpoint.rds.amazonaws.com // For Google Cloud SQL: project:region:instance ```

Repair corrupted database:

```bash # WordPress built-in repair script # Access: https://example.com/wp-admin/maint/repair.php

# Add to wp-config.php first define( 'WP_ALLOW_REPAIR', true );

# Then visit the repair page # Options: # - Repair Database # - Repair and Optimize Database

# Remove the constant after repair // define( 'WP_ALLOW_REPAIR', true );

# Manual repair via MySQL mysql -u username -p database_name

# Check for crashed tables CHECK TABLE wp_posts; CHECK TABLE wp_options; CHECK TABLE wp_comments;

# Repair crashed tables REPAIR TABLE wp_posts; REPAIR TABLE wp_options; REPAIR TABLE wp_comments;

# Or repair all tables mysqlcheck -u username -p --auto-repair --optimize database_name ```

Fix database connection limits:

```bash # Check max connections mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';"

# Check current connections mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"

# If at limit, increase: mysql -u root -p -e "SET GLOBAL max_connections = 500;"

# Make permanent in my.cnf # /etc/mysql/my.cnf or /etc/my.cnf [mysqld] max_connections = 500

# Restart MySQL systemctl restart mysql

# For WordPress, also check persistent connections # wp-config.php define( 'WP_USE_THREADS', true ); ```

### 4. Fix memory exhaustion errors

Increase WordPress memory limit:

```php // wp-config.php define( 'WP_MEMORY_LIMIT', '256M' ); define( 'WP_MAX_MEMORY_LIMIT', '512M' );

// For admin area specifically define( 'WP_ADMIN_AREA_MEMORY_LIMIT', '512M' ); ```

Increase PHP memory limit:

```ini # php.ini or .user.ini memory_limit = 512M max_execution_time = 300 max_input_time = 300 upload_max_filesize = 128M post_max_size = 128M

# Or in .htaccess (Apache) php_value memory_limit 512M php_value max_execution_time 300 php_value upload_max_filesize 128M php_value post_max_size 128M ```

Find memory-hungry plugins:

```php // Add to theme's functions.php temporarily function check_memory_usage() { echo 'Memory: ' . memory_get_usage() . ' bytes<br>'; echo 'Peak: ' . memory_get_peak_usage() . ' bytes<br>'; } add_action( 'wp_footer', 'check_memory_usage' );

// Or use Query Monitor plugin for detailed breakdown ```

### 5. Fix file permission issues

Set correct permissions:

```bash # WordPress file permissions

# All files should be 644 find /var/www/wordpress -type f -exec chmod 644 {} \;

# All directories should be 755 find /var/www/wordpress -type d -exec chmod 755 {} \;

# wp-config.php should be more restrictive chmod 640 /var/www/wordpress/wp-config.php # Or even 440 (read-only) chmod 440 /var/www/wordpress/wp-config.php

# wp-content needs write access for uploads chmod 755 /var/www/wordpress/wp-content chmod 755 /var/www/wordpress/wp-content/uploads chmod -R 755 /var/www/wordpress/wp-content/uploads

# Set correct ownership chown -R www-data:www-data /var/www/wordpress # Or for nginx/php-fpm chown -R nginx:nginx /var/www/wordpress ```

Fix permission issues after backup restore:

```bash # After restoring from backup, fix permissions cd /var/www/wordpress

# Reset ownership chown -R www-data:www-data .

# Reset permissions find . -type f -exec chmod 644 {} \; find . -type d -exec chmod 755 {} \;

# Special directories chmod 775 wp-content chmod 775 wp-content/uploads chmod 775 wp-content/cache # If using caching

# Fix SELinux contexts (if SELinux enabled) chcon -R -t httpd_sys_content_t /var/www/wordpress chcon -R -t httpd_sys_rw_content_t /var/www/wordpress/wp-content chcon -R -t httpd_sys_rw_content_t /var/www/wordpress/wp-content/uploads ```

### 6. Fix plugin/theme conflicts

Safe plugin update procedure:

```bash # Before updating plugins:

# 1. Take backup wp db export backup-before-update.sql tar -czf wp-content-backup.tar.gz wp-content

# 2. Check compatibility wp plugin list --update-available

# 3. Update one at a time wp plugin update akismet # Check site wp plugin update jetpack # Check site

# 4. If update fails, rollback wp plugin install akismet --version=5.2 --force wp plugin activate akismet

# 5. Use WP-CLI for safe updates wp plugin update --all # Better than web interface - shows errors ```

Debug theme functions.php:

```php // Common functions.php errors

// Syntax error - missing semicolon function my_function() { echo "Hello" // Missing semicolon! }

// Fix: function my_function() { echo "Hello"; }

// Function already declared function my_setup() { ... } // In child theme: function my_setup() { ... } // Fatal error!

// Fix: Use different function name or check first if ( ! function_exists( 'my_setup' ) ) { function my_setup() { ... } }

// Missing required WordPress functions // Always check function exists if ( function_exists( 'add_theme_support' ) ) { add_theme_support( 'post-thumbnails' ); }

// Fatal error from undefined class // Use class_exists check if ( class_exists( 'WooCommerce' ) ) { // WooCommerce is active } ```

### 7. Fix .htaccess issues

Regenerate .htaccess:

```bash # Backup existing .htaccess cp .htaccess .htaccess.backup

# Default WordPress .htaccess cat > .htaccess << 'EOF' # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress EOF

# Fix permissions chmod 644 .htaccess ```

Fix common .htaccess errors:

```apache # Error: Invalid command 'RewriteEngine' # Fix: Enable mod_rewrite a2enmod rewrite systemctl restart apache2

# Error: .htaccess override not allowed # Fix: Enable AllowOverride in Apache config # /etc/apache2/sites-available/000-default.conf <Directory /var/www/html> AllowOverride All # Was None </Directory>

# Error: too many redirects (redirect loop) # Fix: Check for conflicting rules # Remove duplicate WordPress rewrite rules # Ensure SSL redirect doesn't conflict

# Error: 500 after security plugin .htaccess rules # Fix: Temporarily rename .htaccess mv .htaccess .htaccess.disabled # Site should load (without pretty permalinks) # Restore and fix rules mv .htaccess.disabled .htaccess ```

### 8. Monitor WordPress health

Enable Site Health:

```bash # WordPress 5.2+ has built-in Site Health # Access: Tools > Site Health

# Check via WP-CLI wp site health status

# Run specific tests wp site health check --tests=plugin_version wp site health check --tests=theme_version wp site health check --tests=wordpress_version

# Get recommended improvements wp site health check --format=json | jq '.[] | select(.status != "good")' ```

Set up monitoring:

```yaml # Uptime monitoring # UptimeRobot, Pingdom, or custom solution

# WordPress-specific monitoring # Install WP-CLI monitoring script

# /usr/local/bin/wp-health-check.sh #!/bin/bash

SITE_URL="https://example.com" ADMIN_URL="https://example.com/wp-admin"

# Check frontend STATUS=$(curl -s -o /dev/null -w "%{http_code}" $SITE_URL) if [ "$STATUS" -ne 200 ]; then echo "CRITICAL: Frontend returned $STATUS" exit 2 fi

# Check admin STATUS=$(curl -s -o /dev/null -w "%{http_code}" -c cookies.txt $ADMIN_URL) if [ "$STATUS" -ne 200 ] && [ "$STATUS" -ne 302 ]; then echo "CRITICAL: Admin returned $STATUS" exit 2 fi

# Check for critical errors in debug log if [ -f wp-content/debug.log ]; then ERRORS=$(tail -100 wp-content/debug.log | grep -c "Fatal error") if [ "$ERRORS" -gt 0 ]; then echo "WARNING: $ERRORS fatal errors in debug log" fi fi

# Check database connection wp db check 2>/dev/null if [ $? -ne 0 ]; then echo "CRITICAL: Database check failed" exit 2 fi

echo "OK: WordPress healthy" exit 0 ```

Prometheus/Grafana monitoring:

```yaml # WordPress exporter for Prometheus # https://github.com/gabinete/wordpress_exporter

scrape_configs: - job_name: 'wordpress' static_configs: - targets: ['localhost:9206']

# Key metrics: # wordpress_up - 1 if healthy # wordpress_php_version_info # wordpress_wp_version_info # wordpress_active_plugins # wordpress_inactive_plugins

# Grafana alert rules groups: - name: wordpress_health rules: - alert: WordPressDown expr: wordpress_up == 0 for: 5m labels: severity: critical annotations: summary: "WordPress site is down" description: "{{ $labels.instance }} is not responding"

  • alert: WordPressPluginUpdateAvailable
  • expr: wordpress_plugins_update_available > 0
  • for: 7d
  • labels:
  • severity: info
  • annotations:
  • summary: "WordPress plugin updates available"
  • `

Prevention

  • Enable automatic updates for minor releases
  • Test plugin/theme updates on staging first
  • Regular backups with verified restoration
  • Monitor disk space and memory usage
  • Use managed WordPress hosting for automatic maintenance
  • Implement proper error logging (not display)
  • Set up uptime monitoring with alerts
  • Keep PHP version current and supported
  • Use child themes for customizations
  • Document custom code and dependencies
  • **403 Forbidden**: Permission denied, often .htaccess or file permissions
  • **404 Not Found**: URL rewrite issues, permalinks need refresh
  • **500 Internal Server Error**: Generic server error, check logs
  • **502 Bad Gateway**: PHP-FPM not running or crashed
  • **503 Service Unavailable**: Maintenance mode stuck or resource exhaustion