WordPress powers a significant portion of the web, making it a prime target for attackers. When security measures go wrong—or when your site is compromised—you need to diagnose and fix issues quickly. This guide walks through the most common WordPress security errors you'll encounter in production environments, with symptoms, root causes, and exact fixes for each.
File Permission Errors
Symptoms
You'll see HTTP 403 Forbidden errors when accessing the admin panel, or WordPress will display "Sorry, you are not allowed to access this page" despite having admin credentials. Plugin uploads fail with permission denied messages, and the theme editor shows write errors.
Root Cause
Incorrect file ownership or overly restrictive permissions prevent WordPress from reading configuration files or writing to necessary directories. This often happens after migrations, manual file transfers, or automated security hardening that went too far.
The Fix
First, verify current ownership and permissions:
ls -la /home/username/public_html/
Set correct ownership (replace username with your cPanel username):
chown -R username:username /home/username/public_html/
Apply standard WordPress permissions:
find /home/username/public_html/ -type d -exec chmod 755 {} \;
find /home/username/public_html/ -type f -exec chmod 644 {} \;
Secure wp-config.php specifically:
chmod 640 /home/username/public_html/wp-config.php
If you're on a shared hosting environment with suPHP or FastCGI, files must be owned by your user account. On VPS environments with Apache running as a different user, you may need group permissions adjusted or ACLs configured.
Malware Infection and Backdoor Files
Symptoms
Unauthorized admin accounts appear in your user list. Your site redirects visitors to spam or phishing pages. Google flags your site as malicious. You find unfamiliar PHP files in uploads directories or theme folders. Server resource usage spikes without explanation.
Root Cause
Outdated WordPress core, themes, or plugins contain exploited vulnerabilities. Weak passwords allow brute-force entry. Nulled or pirated themes ship with backdoors pre-installed.
The Fix
Start by taking your site offline to prevent further damage. Add this to wp-config.php temporarily:
define('WP_MAINTENANCE_MODE', true);
Scan for malware using command-line tools. ClamAV is available on most Linux servers:
clamscan -r /home/username/public_html/ --infected --remove
For WordPress-specific scanning, use WP-CLI with a security plugin:
wp plugin install wordfence --activate
wp wordfence scan
Manually inspect common injection points:
find /home/username/public_html/wp-content/uploads/ -name "*.php" -type f
grep -r "eval(" /home/username/public_html/wp-content/themes/
grep -r "base64_decode" /home/username/public_html/wp-content/plugins/
Remove any unauthorized PHP files from uploads directories—WordPress should never execute PHP from there. Check your .htaccess file for suspicious redirects or injected code.
Reinstall WordPress core files:
wp core download --force --skip-content
Change all passwords: WordPress admin accounts, database user, FTP/SSH, and cPanel. Remove any admin users you don't recognize through wp-admin or directly via database:
wp user list
wp user delete <ID> --reassign=<admin_id>
Review scheduled tasks for malicious cron jobs:
wp cron event list
After cleanup, take your site back online by removing the maintenance mode line from wp-config.php.
Authentication and Login Issues
Symptoms
Valid credentials are rejected with "Invalid username or password." The login page redirects to itself endlessly. Two-factor authentication codes fail consistently. Sessions expire immediately after login.
Root Cause
Corrupted user meta data in the database, conflicting security plugins, incorrect cookie domain settings, or server-side session handling problems.
The Fix
First, verify you can bypass the issue through wp-login.php by clearing all browser cookies and cache. If the problem persists, check for plugin conflicts by renaming the plugins directory via FTP or SSH:
mv /home/username/public_html/wp-content/plugins /home/username/public_html/wp-content/plugins-disabled
Try logging in again. If successful, rename it back and disable plugins one by one to identify the culprit.
Check cookie domain settings in wp-config.php:
define('COOKIE_DOMAIN', '.yourdomain.com');
Ensure your site URL and home URL match:
wp option get siteurl
wp option get home
If they differ or point to the wrong domain, update them:
wp option update siteurl 'https://yourdomain.com'
wp option update home 'https://yourdomain.com'
For database-level user corruption, reset the password directly:
wp user update admin_username --user_pass=new_secure_password
If two-factor authentication is locked out, disable the plugin at the database level:
UPDATE wp_options SET option_value = '' WHERE option_name = 'active_plugins';
Run this through phpMyAdmin or MySQL CLI, then log in and reactivate plugins individually.
SSL/TLS Mixed Content Warnings
Symptoms
Browser shows "Not Secure" despite having a valid SSL certificate. Console errors report blocked mixed content. Images or scripts fail to load on HTTPS pages.
Root Cause
Hardcoded HTTP URLs in theme files, database content, or plugin settings. WordPress configured to serve HTTP when HTTPS is available.
The Fix
Force HTTPS in wp-config.php:
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS'] = 'on';
Update database URLs from HTTP to HTTPS using WP-CLI:
wp search-replace 'http://yourdomain.com' 'https://yourdomain.com' --all-tables
Add HTTPS redirection in .htaccess:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
If behind a proxy or CDN like Cloudflare, ensure your server respects forwarded protocol headers. Most hosting providers handle this automatically, but you may need to add the X-Forwarded-Proto check shown above.
Verify your SSL certificate is valid and covers your domain:
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
Check the output for certificate chain completeness and expiration dates.
Database Connection Errors
Symptoms
"Error establishing a database connection" message on all pages. WordPress admin panel is completely inaccessible. The site worked fine minutes or hours ago.
Root Cause
Wrong database credentials in wp-config.php, MySQL service stopped, corrupted database tables, or hosting account exceeding connection limits.
The Fix
Verify MySQL is running:
systemctl status mysql
If stopped, start it:
systemctl start mysql
On shared hosting, you won't have systemctl access—contact your hosting provider if the database service is down.
Test database credentials from command line:
mysql -u db_user -p -h localhost db_name
If this fails, your wp-config.php credentials are incorrect. Retrieve correct credentials from cPanel > MySQL Databases or your hosting control panel.
Check for corrupted tables:
wp db check
Repair if needed:
wp db repair
Alternatively, add this to wp-config.php temporarily:
define('WP_ALLOW_REPAIR', true);
Visit yourdomain.com/wp-admin/maint/repair.php and remove the line after repairs complete.
If you're hitting connection limits, check current connections:
mysql -e "SHOW PROCESSLIST;"
Optimize persistent connections in wp-config.php:
define('WP_USE_EXT_MYSQL', false);
XML-RPC Brute Force Attacks
Symptoms
Server CPU and bandwidth usage spike. Access logs show thousands of POST requests to xmlrpc.php. Site becomes slow or unresponsive.
Root Cause
XML-RPC is a WordPress API endpoint that allows remote commands. Attackers exploit it for brute-force password guessing and DDoS amplification because a single request can try multiple passwords.
The Fix
Disable XML-RPC if you don't need it. Add to .htaccess:
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
Or block it at the server level in your nginx config:
location = /xmlrpc.php {
deny all;
}
If you need XML-RPC for Jetpack or mobile apps, restrict it to specific IPs:
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
Allow from 192.0.64.0/18
Allow from YOUR_IP
</Files>
Monitor your logs for attack patterns:
grep "POST /xmlrpc.php" /var/log/apache2/access.log | wc -l
Implement rate limiting with fail2ban. Create /etc/fail2ban/filter.d/wordpress-xmlrpc.conf:
[Definition]
failregex = ^<HOST> .* "POST /xmlrpc.php
Add to /etc/fail2ban/jail.local:
[wordpress-xmlrpc]
enabled = true
filter = wordpress-xmlrpc
logpath = /var/log/apache2/access.log
maxretry = 10
bantime = 3600
Restart fail2ban:
systemctl restart fail2ban
Plugin and Theme Security Updates Failing
Symptoms
Update notifications appear but clicking "Update Now" fails silently or shows errors. Automatic updates don't run. The site shows "Briefly unavailable for scheduled maintenance" indefinitely.
Root Cause
File permission problems prevent WordPress from writing updates. Insufficient PHP memory or execution time. A failed update left a .maintenance file in place.
The Fix
Check for stuck maintenance mode:
ls -la /home/username/public_html/.maintenance
Remove it if found:
rm /home/username/public_html/.maintenance
Verify wp-content is writable by the web server:
chmod 755 /home/username/public_html/wp-content/
chmod -R 755 /home/username/public_html/wp-content/plugins/
chmod -R 755 /home/username/public_html/wp-content/themes/
Increase PHP limits in wp-config.php:
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Update via WP-CLI instead of the admin interface:
wp plugin update --all
wp theme update --all
wp core update
For hosts that disable filesystem writes, enable direct filesystem access in wp-config.php:
define('FS_METHOD', 'direct');
Only use this if file ownership is correct; otherwise it's a security risk.
Checklist: Post-Incident Security Hardening
After resolving any security issue, implement these measures to prevent recurrence:
- Change all passwords: admin users, database, FTP, SSH, hosting panel
- Update WordPress core, all plugins, all themes
- Remove unused plugins and themes entirely
- Implement automated backups with off-server storage
- Install a security plugin (Wordfence, Sucuri, iThemes Security)
- Enable two-factor authentication for all admin accounts
- Limit login attempts with a plugin or server-level rules
- Disable file editing in wp-admin:
define('DISALLOW_FILE_EDIT', true);
- Move wp-config.php one directory above web root
- Add security headers to .htaccess or server config
- Review user accounts and remove any with unnecessary privileges
- Set up monitoring for file changes and unauthorized logins
- Document your recovery process for the next incident
Conclusion
WordPress security troubleshooting requires methodical diagnosis—identify symptoms, understand the root cause, apply the specific fix, then harden against recurrence. Most errors fall into predictable categories: permissions, malware, authentication, SSL configuration, database connectivity, XML-RPC abuse, and update failures. With the commands and procedures in this guide, you can resolve incidents quickly and implement preventive measures that reduce future risk. Document your fixes and maintain current backups—when the next issue arrives, you'll be prepared.
