Solucionar WordPress “There has been a critical error”: habilitar WP_DEBUG y recuperar el sitio

¿Te fue útil?

Si tu sitio WordPress acaba de caerse mostrando “There has been a critical error on this website”, no estás solo. El mensaje es intencionadamente vago: estupendo para la experiencia de usuario y terrible para la persona de guardia. Esa persona eres tú.

La buena noticia: la mayoría de los “errores críticos” son simples—una actualización de plugin defectuosa, una función del tema que llama algo que ya no existe, o PHP quedándose sin memoria. El truco es pasar de “algo se rompió” a una traza de pila concreta, rápido, sin convertir tu servidor de producción en un diario público de depuración.

Qué significa realmente el “critical error” de WordPress

Ese banner es WordPress siendo cortés frente a un error fatal de PHP. Algo lanzó una excepción o alcanzó una condición fatal y PHP dejó de ejecutar. WordPress no pudo renderizar la página, así que mostró el fallback de “critical error”. En épocas anteriores verías la “pantalla blanca de la muerte” (WSOD). Hoy obtienes un mensaje más amigable y, a veces, un correo al admin con un enlace de recuperación.

En un sistema funcionando, un error fatal debería dejar rastro: logs de PHP-FPM, logs de Apache/Nginx, un log de depuración de WordPress (si está habilitado) y, a veces, trazas de un monitor de rendimiento. Tu trabajo es reunir la primera traza útil y luego tomar una decisión limpia: revertir, desactivar, parchear o restaurar.

Qué no es

  • No es un fallo de inicio de sesión a la base de datos. Eso suele mostrar “Error establishing a database connection”.
  • No necesariamente es una caída del servidor. Tu servidor web puede estar sano mientras PHP se estrellaba.
  • No prueba que WordPress sea “inestable”. Prueba que alguien lanzó código que no coincide con la realidad (versiones, dependencias, supuestos).

Guía de diagnóstico rápido (primero/segundo/tercero)

Cuando un sitio de producción está caído, no “empiezas a explorar”. Ejecutas un playbook corto y fuerzas al sistema a decirte qué pasó.

Primero: confirma que es un fatal de PHP y obtén la línea exacta del error

  • Revisa el log de errores del servidor web y el log de PHP-FPM de los últimos minutos.
  • Si ves una traza de pila que mencione la ruta de un plugin o tema, ya tienes un objetivo.
  • Si los logs están vacíos o son inútiles, habilita el registro de depuración de WordPress a archivo solamente y recarga una vez.

Segundo: aisla el cambio que lo desencadenó

  • Pregunta: ¿qué cambió? ¿Actualización automática de un plugin, actualización del tema, upgrade de PHP, nuevo MU plugin, endurecimiento de seguridad?
  • Revierte el cambio más reciente primero. No hagas cinco “arreglos” y luego te preguntes cuál fue el que funcionó.

Tercero: restaura el servicio con la solución menos arriesgada

  • Desactiva el plugin problemático (renombra el directorio o usa WP-CLI) y vuelve a poner el sitio en línea.
  • Cambia a un tema por defecto si el tema es el culpable.
  • Si los archivos core están corruptos, reinstala el core (sin tocar wp-content).
  • Si nada más funciona: restaura desde una copia conocida buena y luego aplica los cambios con cuidado.

Sí, puedes pasarte una hora depurando el bug subyacente. Pero si el CEO está mirando la carga de la página en su teléfono, primero haces que cargue.

Algunos datos e historia útiles (para que dejes de adivinar)

  1. WordPress introdujo el “modo de recuperación por error fatal” en 5.2 (2019), incluyendo correos al admin y un enlace de “recuperación” cuando un plugin/tema falla.
  2. El clásico WSOD a menudo era “solo” la salida fatal de PHP suprimida por display_errors=Off y sin configuración de logs—silencio, no ausencia.
  3. WP_DEBUG es una constante de WordPress, no una configuración de PHP. Cambia el comportamiento de WP (notificaciones principalmente) pero no reemplaza el registro de errores de PHP.
  4. WP_DEBUG_LOG puede registrar en wp-content/debug.log incluso cuando los errores no se muestran a los usuarios—útil, y también un riesgo de privacidad si se configura mal.
  5. Muchos errores críticos son por desalineación de versiones. El plugin requiere PHP 8.1; el servidor usa PHP 7.4. O el plugin espera hooks de WordPress que llegaron en un core más nuevo.
  6. La caché de opcode (OPcache) puede hacer que los rollbacks parezcan “ignorados”. Despliegas un arreglo, pero el bytecode antiguo persiste hasta que se limpia la caché.
  7. Las actualizaciones automáticas redujeron el tiempo de parcheo pero aumentaron las caídas sorpresa. Especialmente en sitios con plugins que “funcionan en staging” y sin tests de integración.
  8. Algunos hosts interceptan errores de PHP y muestran su propia página amigable, lo que puede ocultar la falla real a menos que inspecciones logs del lado del servidor.

Una verdad operativa más: WordPress es una app PHP que corre en un ecosistema compartido de servidor web + handler PHP + sistema de archivos + base de datos + caché. La mayoría de las caídas son en los bordes entre esas partes, no “WordPress en sí”.

Reglas de seguridad antes de tocar WP_DEBUG

Depurar es donde las buenas intenciones se convierten en fugas de datos. Sé deliberado.

  • Nunca habilites la visualización pública de errores en producción. Eso significa: mantiene WP_DEBUG_DISPLAY desactivado, mantiene PHP display_errors apagado.
  • Registra a archivo, no al navegador. La salida al navegador puede exponer secretos, rutas y tokens a todo el mundo, incluidos rastreadores.
  • Asume que los logs de depuración contienen datos personales. Correos, cookies, a veces cabeceras de petición—depende de lo que los plugins vuelquen.
  • Limita el tiempo. Habilita el registro, reproduce una vez, captura la traza, luego desactiva o rota los logs.
  • No hagas “chmod 777” para salir del paso. Arreglarás el error y crearás otro más grande.

Broma #1: Habilitar WP_DEBUG_DISPLAY en producción es como anunciar tus contraseñas por el micrófono de un estadio—técnicamente eficiente, socialmente catastrófico.

Habilitar WP_DEBUG correctamente (y capturar el error real)

Debes habilitar tres cosas en wp-config.php: modo debug, registro a archivo y sin visualización. Opcional: establecer una ruta de log personalizada fuera de la raíz web (mejor). También considera desactivar la concatenación de scripts, lo que puede ayudar al depurar problemas JS del admin, aunque eso normalmente no es el caso de “error crítico”.

Configuración recomendada y segura para producción

Coloca esto antes de la línea que dice /* That's all, stop editing! */. Si no ves esa línea, tu wp-config.php puede estar personalizado; aún así colócalos antes de que WordPress cargue.

cr0x@server:~$ sudo sed -n '1,180p' /var/www/html/wp-config.php
...output...

Lo que quieres añadir (mostrado aquí como un modelo mental estilo parche, no como un comando literal) es:

  • define('WP_DEBUG', true);
  • define('WP_DEBUG_LOG', true); o una ruta como /var/log/wordpress/debug.log
  • define('WP_DEBUG_DISPLAY', false);
  • @ini_set('display_errors', 0); (defensa en profundidad; la configuración de PHP debería ya hacerlo)

Opinión: si puedes, registra en /var/log/wordpress/ con permisos restringidos, no en wp-content/debug.log. Demasiadas configuraciones sirven accidentalmente archivos desde wp-content si alguien configura mal Nginx o añade una regla permisiva.

Después de capturar el error, desactívalo

El modo debug no es un estilo de vida. Es una herramienta diagnóstica. Si lo dejas activado inflarás logs, filtrarás rutas y degradarás rendimiento con avisos excesivos.

Tareas prácticas: comandos, salidas y decisiones (12+)

A continuación hay tareas reales que puedes ejecutar por SSH. Cada una incluye: el comando, qué significa la salida y qué decisión tomar. Ajusta rutas para tu distro y layout de vhost. Cuando dudes, busca en tus configs en lugar de fiarte de la memoria.

Task 1: Verify the site is actually failing the way users see it

cr0x@server:~$ curl -I https://example.com/
HTTP/2 500
date: Thu, 26 Dec 2025 12:11:09 GMT
content-type: text/html; charset=UTF-8

Meaning: HTTP 500 confirms server-side failure (not just a browser cache issue).

Decision: Move to server logs immediately; don’t waste time in wp-admin links that won’t load.

Task 2: Check Nginx error log around the incident window

cr0x@server:~$ sudo tail -n 80 /var/log/nginx/error.log
2025/12/26 12:10:58 [error] 2211#2211: *184 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function wp_get_environment_type() in /var/www/html/wp-content/plugins/acme-cache/acme-cache.php:91
Stack trace:
#0 /var/www/html/wp-settings.php(526): include_once()
#1 /var/www/html/wp-config.php(102): require_once('...')
#2 /var/www/html/wp-load.php(50): require_once('...')
#3 /var/www/html/wp-blog-header.php(13): require_once('...')
#4 /var/www/html/index.php(17): require('...')
#5 {main}
  thrown in /var/www/html/wp-content/plugins/acme-cache/acme-cache.php on line 91" while reading response header from upstream, client: 203.0.113.44, server: example.com, request: "GET / HTTP/2.0", upstream: "fastcgi://unix:/run/php/php8.1-fpm.sock:", host: "example.com"

Meaning: You have the smoking gun: plugin acme-cache calls a WordPress function not available in this core version.

Decision: Disable that plugin first to restore service, then address version compatibility.

Task 3: Check PHP-FPM pool log (if Nginx doesn’t show enough)

cr0x@server:~$ sudo tail -n 60 /var/log/php8.1-fpm.log
[26-Dec-2025 12:10:58] WARNING: [pool www] child 3112 said into stderr: "PHP Fatal error:  Uncaught Error: Call to undefined function wp_get_environment_type() in /var/www/html/wp-content/plugins/acme-cache/acme-cache.php:91"

Meaning: Confirms it’s not an Nginx parsing fluke; it’s PHP dying.

Decision: Proceed with plugin disable; no need to enable WP_DEBUG yet if logs already show the trace.

Task 4: Enable WP debug logging (file only) for cases where logs are silent

cr0x@server:~$ sudo grep -n "WP_DEBUG" -n /var/www/html/wp-config.php

Meaning: Empty output means debug constants aren’t set.

Decision: Add production-safe debug settings. If output shows conflicting definitions, fix duplicates (first definition wins in surprising ways).

Task 5: Create a safer log directory outside web root

cr0x@server:~$ sudo install -d -o www-data -g www-data -m 0750 /var/log/wordpress

Meaning: Directory exists, owned by the web user, readable only by owner/group.

Decision: Use /var/log/wordpress/debug.log as WP_DEBUG_LOG target.

Task 6: Edit wp-config.php safely and verify syntax

cr0x@server:~$ sudo php -l /var/www/html/wp-config.php
No syntax errors detected in /var/www/html/wp-config.php

Meaning: Your edit didn’t introduce a parse error. Yes, people do this at 2 a.m.

Decision: If you see “Parse error,” revert immediately; a parse error will brick everything, including WP recovery mode.

Task 7: Trigger one request and inspect the WordPress debug log

cr0x@server:~$ curl -sS -o /dev/null -w "%{http_code}\n" https://example.com/
500
cr0x@server:~$ sudo tail -n 80 /var/log/wordpress/debug.log
[26-Dec-2025 12:12:11 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function wp_get_environment_type() in /var/www/html/wp-content/plugins/acme-cache/acme-cache.php:91

Meaning: Debug log confirms the failing file/line.

Decision: Disable that plugin; don’t keep refreshing and generating noise.

Task 8: Disable a plugin without wp-admin by renaming its directory

cr0x@server:~$ cd /var/www/html/wp-content/plugins
cr0x@server:~$ sudo mv acme-cache acme-cache.disabled

Meaning: WordPress can’t load the plugin; it will mark it inactive.

Decision: Reload site. If it returns 200, you’ve restored service; then investigate compatibility and update strategy.

Task 9: Use WP-CLI to list plugins and deactivate cleanly (preferred when possible)

cr0x@server:~$ cd /var/www/html
cr0x@server:~$ sudo -u www-data wp plugin list --status=active
+-------------------+----------+--------+---------+
| name              | status   | update | version |
+-------------------+----------+--------+---------+
| woocommerce       | active   | none   | 8.2.1   |
| acme-cache        | active   | none   | 3.4.0   |
+-------------------+----------+--------+---------+
cr0x@server:~$ sudo -u www-data wp plugin deactivate acme-cache
Plugin 'acme-cache' deactivated.

Meaning: WP-CLI can talk to your WordPress install; that’s a strong sign DB is reachable and core loads at least partly.

Decision: Prefer WP-CLI deactivation over directory renames for cleaner state—unless the fatal prevents WP-CLI from booting.

Task 10: Check current WordPress core version and compare to plugin requirements

cr0x@server:~$ sudo -u www-data wp core version
5.6.14

Meaning: Core is old. Many modern plugins assume newer functions exist.

Decision: Plan a controlled core update in staging, not a panicked production upgrade—unless security forces your hand.

Task 11: Switch theme to a default one to rule out theme fatals

cr0x@server:~$ sudo -u www-data wp theme list
+------------------+----------+--------+---------+
| name             | status   | update | version |
+------------------+----------+--------+---------+
| twentytwentyfour | inactive | none   | 1.2     |
| custom-corp      | active   | none   | 9.7     |
+------------------+----------+--------+---------+
cr0x@server:~$ sudo -u www-data wp theme activate twentytwentyfour
Success: Switched to 'Twenty Twenty-Four' theme.

Meaning: If the site comes back, the theme is the culprit (often functions.php or a custom include).

Decision: Keep default theme temporarily to restore service, then fix theme code in a controlled deploy.

Task 12: Confirm PHP version and modules (common compatibility landmine)

cr0x@server:~$ php -v
PHP 8.1.2 (cli) (built: Jan 15 2025 10:22:01) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.2, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.2, Copyright (c), by Zend Technologies

Meaning: CLI PHP version is 8.1. That’s not always the same as the FPM version, but it’s a hint.

Decision: Also check which PHP-FPM socket you’re using in Nginx/Apache. Version skew between CLI and FPM leads to absurd debugging sessions.

Task 13: Identify the PHP-FPM backend used by the site

cr0x@server:~$ sudo grep -R "fastcgi_pass" -n /etc/nginx/sites-enabled | head
/etc/nginx/sites-enabled/example.conf:42: fastcgi_pass unix:/run/php/php8.1-fpm.sock;

Meaning: Nginx is explicitly using php8.1-fpm.

Decision: If the socket points to an older/newer PHP than expected, align it. Lots of “critical errors” are just “wrong PHP.”

Task 14: Check memory limit issues (fatal errors that look random)

cr0x@server:~$ sudo -u www-data wp eval 'echo ini_get("memory_limit"), PHP_EOL;'
128M

Meaning: Memory limit is 128M. For modern WooCommerce + page builders, that can be tight.

Decision: If logs show “Allowed memory size exhausted,” raise memory limit in PHP-FPM pool or php.ini and re-test. Don’t blindly set it to 2G; fix the hog too.

Task 15: Check disk space and inode exhaustion (yes, this breaks WordPress)

cr0x@server:~$ df -h /var/www /var/log
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   38G  1.2G  97% /
cr0x@server:~$ df -i /var/www
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/vda1      2621440 2620000   1440  100% /

Meaning: Inodes are effectively exhausted. PHP can fail writing sessions, caches, uploads, logs. Errors cascade.

Decision: Clean up small-file explosions (cache directories, old backups, debug logs), then consider moving uploads/cache to separate storage.

Task 16: Check database connectivity from WP-CLI

cr0x@server:~$ sudo -u www-data wp db check
Success: Database checked.

Meaning: DB is reachable and tables are OK at a basic level.

Decision: If this fails, stop blaming plugins; fix DB credentials, MySQL availability, or permissions first.

Task 17: Clear OPcache (when you’re sure your deploy is correct but behavior isn’t)

cr0x@server:~$ sudo systemctl reload php8.1-fpm

Meaning: Reload typically flushes OPcache and restarts workers gracefully (depends on config).

Decision: Use reload after code changes when symptoms don’t match the filesystem. If you need a hard reset, restart—but be mindful of concurrency and traffic.

Rutas de recuperación: plugins, temas, core, PHP

Path A: A plugin update broke the site

Esto es lo más común. El modo de fallo es: el plugin asume que existe una función/clase, introdujo un error de sintaxis o ahora requiere una versión de PHP más nueva.

Haz esto:

  • Desactiva el plugin (WP-CLI deactivate, o renombra el directorio).
  • Pon el sitio en línea.
  • Luego decide: actualiza core/PHP para cumplir requisitos, o vuelve el plugin a una versión compatible.

Evita esto: dejar el plugin desactivado sin entender qué hacía. Si gestionaba caché, seguridad, pagos o formularios, puedes haber restaurado la página principal pero roto ingresos silenciosamente.

Path B: El tema está causando fatales (functions.php es una escena del crimen)

Los temas suelen incrustar código tipo “mini framework”. Los temas personalizados en particular llaman funciones de plugins que asumen activos. Entonces alguien desactiva el plugin y el tema se cae.

  • Cambia a un tema por defecto vía WP-CLI.
  • Si WP-CLI no arranca, renombra wp-content/themes/custom-theme y WordPress hará fallback.
  • Una vez estable, arregla el tema para que gestione de forma elegante dependencias faltantes.

Path C: Core desalineado o corrupto

A veces el “critical error” ocurre porque faltan archivos core (deploy malo) o fueron modificados (compromiso, o un plugin escribió donde no debía).

Solución: reinstala el core de WordPress sin tocar wp-content y wp-config.php.

cr0x@server:~$ cd /var/www/html
cr0x@server:~$ sudo -u www-data wp core verify-checksums
Warning: File should not exist: wp-includes/some-stray-file.php
Error: Checksum verification failed.

Decision: Si fallan los checksums, reinstala core (wp core download --force) y luego verifica de nuevo. Si hay archivos inesperados, trátalo como incidente de seguridad hasta que se demuestre lo contrario.

Path D: Una actualización de PHP rompió un plugin (o la arregló y expuso bugs antiguos)

Las actualizaciones de PHP son geniales hasta que no lo son. Funciones deprecadas pueden volverse fatales, la tipificación estricta se endurece y las librerías se comportan diferente.

Estrategia:

  • Confirma qué versión de PHP usa el handler web (FPM) y compárala con lo que soportan tu WordPress y plugins.
  • Si debes degradar temporalmente, hazlo limpiamente (cambia el socket FPM, recarga el servidor web), no editando symlinks al azar.
  • A largo plazo: actualiza plugins/temas para que sean compatibles; no congeles PHP para siempre. Eso acaba con tu sistema convertido en un museo expuesto a Internet.

Path E: Agotamiento de recursos (memoria, disco, CPU) que desencadena fallos en cascada

El “critical error” de WordPress puede ser el síntoma visible de un servidor que ya está muriendo. Cuando la máquina tiene poco disco o memoria, escribir archivos de sesión falla, los directorios de caché no se actualizan y los workers PHP se caen.

Arregla la plataforma primero: libera espacio, rota logs, corrige límites de memoria, añade swap si hace falta (como parche temporal) y reduce el número de workers PHP-FPM si está sobrecargando la máquina.

Broma #2: Lo único que crece más rápido que los plugins de WordPress es el log de depuración que olvidaste rotar.

Tres micro-relatos corporativos desde el campo

Mini-story 1: La caída causada por una suposición incorrecta

Una compañía minorista mediana usaba WordPress para páginas de marketing y otra plataforma para el checkout. Alguien instaló un plugin de rendimiento que “requiere WordPress 5.8+” pero el sitio estaba fijado en 5.6 por compatibilidad con un page builder legado. Nadie vio la línea de requisitos porque el plugin se instaló bien y el entorno de staging era más nuevo que producción.

Un lunes por la mañana, las actualizaciones automáticas actualizaron a una versión mayor del plugin. El plugin empezó a llamar a una función del core introducida después de 5.6. El resultado fue un fatal inmediato en cada petición. El monitor de uptime alertó, el equipo de marketing gritó más fuerte y el equipo de infraestructura fue culpado por “problemas de servidor” porque el sitio devolvía HTTP 500.

La solución fue simple: desactivar el plugin renombrando su directorio, restaurar servicio y luego alinear entornos. La lección real fue más fea: staging se había ido desincronizando. Todos asumieron “staging = production” porque decir eso suena profesional. No era cierto.

Después del incidente, pusieron una puerta aburrida: un job nocturno que compara la versión del core, la versión de PHP-FPM y los plugins activos entre staging y producción. La próxima vez que un plugin requiriera un core más nuevo, vieron la desalineación antes que los usuarios.

Mini-story 2: La optimización que salió mal

Un gran sitio de comunicaciones internas era lento en el área de administración. Un ingeniero habilitó un caching de objetos agresivo y movió sesiones al filesystem por “simplicidad”. También ajustó PHP-FPM para ejecutar más workers, porque el gráfico de CPU “no parecía alto”. Fue el movimiento clásico: optimizar la métrica que puedes ver e ignorar la que no mides.

En días, el servidor empezó a mostrar errores críticos intermitentes. No constantes—peores. Los usuarios recargaban y a veces funcionaba. Los logs mostraban mezcla: “Allowed memory size exhausted”, “failed to open stream” y timeouts de base de datos ocasionales. La reacción inmediata fue culpar a WordPress, luego a MySQL, luego a la red, porque son objetivos emocionalmente satisfactorios.

La causa raíz: agotamiento de inodos y contención de disco por una implementación de caché que escribía miles de archivos pequeños combinada con demasiados workers PHP-FPM que golpeaban el disco. Cuando el filesystem no podía crear nuevos archivos de cache/sesión, las llamadas PHP fallaban en lugares inesperados y los plugins gestionaban mal esas fallas, conduciendo a fatales.

Revirtieron el caching basado en archivos, migraron a un servicio de caché en memoria y redujeron workers PHP-FPM para ajustar la capacidad de IO. El rendimiento mejoró y los errores críticos “aleatorios” desaparecieron. La moraleja: el cuello de botella que ignoras elegirá su momento para darte una lección.

Mini-story 3: La práctica aburrida pero correcta que salvó el día

Un equipo de servicios financieros ejecutaba WordPress en un entorno muy controlado: sin actualizaciones automáticas en producción, cambios desplegados por CI y una ventana de mantenimiento semanal. No era sexy, pero era predecible. También tenían un procedimiento de restauración probado: no “tenemos backups”, sino “restauramos ayer y funcionó”.

Una tarde, una redactora instaló un plugin en staging para previsualizar una función. Bien. Excepto que la rutina de desinstalación del proveedor del plugin era buggy y dejó un archivo MU en wp-content/mu-plugins. Ese archivo llegó al artefacto de release y se desplegó a producción durante la ventana.

El sitio pegó un error crítico inmediato por una dependencia ausente que el MU plugin asumía. El ingeniero on-call siguió el runbook: confirmar fatal en logs, desactivar el MU plugin moviendo el archivo, recargar PHP-FPM, verificar 200s. El servicio se restauró rápido.

Luego la práctica aburrida importó: avanzaron con un release corregido y usaron herramientas de diff para demostrar exactamente qué cambió. Sin misterio. Sin “tal vez fue la base de datos”. El informe de incidente fue corto, factual y útil—que es el mejor tipo.

Errores comunes: síntoma → causa raíz → solución

Esta sección existe porque la gente sigue repitiendo los mismos errores, y me gusta no repetir el mismo incidente dos veces.

1) Síntoma: “Critical error” solo en ciertas páginas

Causa raíz: Un plugin dispara un fatal solo cuando se carga un shortcode, plantilla o ruta de WooCommerce específica.

Solución: Golpea la URL que falla mientras haces tail de logs. Desactiva el plugin/componente del tema que engancha esa ruta. Si es por contenido (shortcode), edita el post en la base de datos o via WP-CLI para eliminar temporalmente el shortcode.

2) Síntoma: Sitio caído, wp-admin también caído, WP-CLI falla con un fatal

Causa raíz: Un must-use plugin o un archivo cargado muy temprano falla antes de que WP pueda bootstrappear.

Solución: Revisa wp-content/mu-plugins. Mueve archivos fuera uno por uno. También mira advanced-cache.php y object-cache.php en wp-content (drop-in plugins).

3) Síntoma: Habilitaste WP_DEBUG y ahora los visitantes ven errores crudos

Causa raíz: WP_DEBUG_DISPLAY o PHP display_errors está activado.

Solución: Establece define('WP_DEBUG_DISPLAY', false); y asegúrate que la config de PHP tenga display_errors=Off. Recarga PHP-FPM. Confirma con una petición de prueba; los errores deberían ir solo al log.

4) Síntoma: “Arreglaste” el plugin pero el error persiste

Causa raíz: OPcache sirve bytecode antiguo, o editaste el servidor equivocado (multi-nodo, contenedor equivocado, volumen equivocado).

Solución: Recarga/reinicia PHP-FPM, confirma el contenido del archivo en el host que sirve tráfico y verifica los targets del load balancer. No confíes en tu prompt SSH; verifica.

5) Síntoma: Error crítico tras migrar hosts

Causa raíz: Faltan extensiones PHP (mbstring, intl), permisos/propietario de archivos incorrectos, o versión de PHP incompatible.

Solución: Compara la lista de módulos y versión de PHP; corrige la propiedad al usuario web; asegúrate de que WordPress pueda leer/escribir donde necesita (wp-content/uploads, dirs de caché).

6) Síntoma: “Allowed memory size exhausted” en logs

Causa raíz: Límite de memoria PHP bajo, plugin descontrolado o opciones autoload enormes en la base de datos.

Solución: Aumenta memoria a un nivel sensato (256M suele ser razonable), luego perfila. Usa WP-CLI para inspeccionar opciones autoload y quitar las que molesten.

7) Síntoma: debug.log crece rápidamente y llena disco

Causa raíz: WP_DEBUG dejado activo; plugin emite avisos/repetidos; no hay rotación de logs.

Solución: Desactiva WP_DEBUG después de capturar. Añade logrotate para la ruta del log. Arregla el código spammy del plugin/tema.

8) Síntoma: Error crítico aparece, luego desaparece, luego vuelve

Causa raíz: Un nodo en un clúster tiene diferente conjunto de plugins, diferente filesystem o diferente versión de PHP.

Solución: Compara nodos: directorios de plugins, checksums, versiones PHP-FPM, volúmenes montados. Haz despliegues inmutables y consistentes.

Listas de verificación / plan paso a paso

Checklist de restauración inmediata (objetivo: menos de 15 minutos)

  1. Confirma código de estado y alcance: una URL, todas las URLs, admin también.
  2. Tarea logs Nginx/Apache y PHP-FPM para el mensaje fatal exacto.
  3. Si los logs están silenciosos: habilita WP_DEBUG con WP_DEBUG_LOG y WP_DEBUG_DISPLAY=false.
  4. Identifica si el fatal referencia un plugin o ruta de tema.
  5. Desactiva el plugin/tema sospechoso (WP-CLI preferido; renombra directorio/archivo si es necesario).
  6. Recarga PHP-FPM para limpiar OPcache si el comportamiento no coincide con el filesystem.
  7. Vuelve a probar: curl por 200, luego carga la homepage en un navegador, luego prueba rutas clave (login, checkout, formulario de contacto).
  8. Captura la traza de pila y anota el cambio que desencadenó el incidente.
  9. Apaga WP_DEBUG (o al menos para de loguear verbosamente) después de tener la evidencia.

Checklist de causa raíz y prevención de repetición (objetivo: mismo día)

  1. Compara versiones: core de WordPress, PHP-FPM, plugins activos, tema.
  2. Revisa cambios recientes: auto-updates, deploys, cambios de config, migraciones de host.
  3. Reproduce en staging con versiones que coincidan.
  4. Decide la estrategia: actualizar core/PHP, fijar versiones de plugin o reemplazar plugin.
  5. Añade un guardrail: desactiva auto-updates para plugins de riesgo o permite actualizaciones solo vía CI.
  6. Implementa rotación de logs para los debug logs de WordPress y logs web/PHP.
  7. Añade una prueba de humo: fetch de homepage + rutas clave después de cada deploy.

Checklist mínimo y seguro para WP_DEBUG

  • WP_DEBUG true solo mientras diagnosticas.
  • WP_DEBUG_LOG a una ruta protegida.
  • WP_DEBUG_DISPLAY false.
  • PHP display_errors off.
  • Controles de acceso para que los archivos de log no sean web-accesibles.

Una cita operativa para tener a mano

Idea parafraseada (atrib. a W. Edwards Deming): Sin datos, eres solo otra persona con una opinión.

WP_DEBUG, usado correctamente, es cómo conviertes un outage de “opiniones” a “aquí está la línea exacta que se rompió”.

Preguntas frecuentes

1) ¿Por qué WordPress muestra “There has been a critical error” en lugar del error real?

Porque mostrar errores crudos de PHP a los usuarios es un riesgo de seguridad y privacidad. WordPress oculta los detalles y espera que consultes logs del servidor o habilites un debug seguro.

2) ¿Habilitar WP_DEBUG ralentizará mi sitio?

Puedes verlo así. Aumenta el logging y muestra avisos que algunos plugins generan constantemente. Úsalo brevemente, registra a archivo y luego desactívalo. Para observabilidad a largo plazo usa logging estructurado y monitoreo adecuado.

3) ¿Es seguro wp-content/debug.log?

A veces. Depende de las reglas del servidor web. Si tu servidor puede servir archivos desde wp-content directamente (común), corres el riesgo de exponer el log. Una ruta protegida como /var/log/wordpress es más segura.

4) No puedo acceder a wp-admin. ¿Cómo desactivo plugins?

Usa WP-CLI si arranca. Si no, renombra el directorio del plugin bajo wp-content/plugins o mueve el archivo fuera de mu-plugins. WordPress omitirá lo que no encuentre.

5) ¿Qué pasa si desactivar todos los plugins no lo arregla?

Entonces mira el tema, los MU plugins y los drop-ins (object-cache.php, advanced-cache.php). Si ninguno, verifica checksums del core y revisa versión/extensiones PHP y salud del filesystem (disco/inodos).

6) ¿Cómo sé si es un problema de memoria de PHP?

Tus logs dirán “Allowed memory size exhausted.” No adivines. Confirma límite de memoria vía WP-CLI o phpinfo (de forma segura), súbelo moderadamente y luego busca el plugin/tema que causa el pico.

7) ¿Por qué el error solo ocurre a veces?

Las fallas intermitentes suelen significar que un nodo del clúster difiere, o el agotamiento de recursos es periódico (cron, backups, reconstrucciones de caché), o OPcache sirve código obsoleto en algunos workers.

8) ¿Debería restaurar desde backup de inmediato?

Si no puedes identificar rápidamente el componente que falla y el impacto en el negocio es alto, sí—restaurar es una respuesta válida. Pero captura logs primero, de lo contrario repetirás la caída en la próxima actualización.

9) ¿Puedo “arreglar” esto reinstalando WordPress?

Puedes reinstalar el core de forma segura, pero rara vez soluciona bugs de compatibilidad de plugins/temas. Reinstalar todo suele ser una forma dramática de evitar leer la traza de la pila.

10) ¿Cómo prevengo esta clase de incidentes?

Deja de usar producción como tu entorno de integración: fija versiones, prueba actualizaciones en staging que coincida con producción, despliega por CI y mantén un procedimiento de rollback/restore que realmente hayas practicado.

Conclusión: siguientes pasos para evitar reincidencias

“There has been a critical error” es WordPress diciéndote: “PHP murió, por favor ve a leer los recibos.” Tu camino más rápido es consistente: revisa logs del servidor, habilita el registro WP_DEBUG de forma segura si hace falta, aisla el plugin/tema culpable, restaura servicio y luego arregla la desalineación de versiones o el bug en forma controlada.

Haz esto a continuación:

  • Apaga WP_DEBUG si lo habilitaste, o al menos detén el logging verboso una vez que tengas la traza.
  • Anota el desencadenante: qué actualización, qué deploy, qué cambio de configuración.
  • Haz que staging coincida con producción (versiones, handler PHP, plugins). La deriva es cómo acabas depurando ficción.
  • Añade una prueba de humo automatizada tras las actualizaciones: homepage + login + una ruta clave de negocio. Barato y efectivo.
  • Rota logs y vigila disco/inodos. Las caídas por discos llenos no son “misteriosas”, solo embarazosas.

Si no haces nada más, haz esto: trata las actualizaciones de WordPress como releases de software, no como ruido de fondo. Producción ya tiene suficientes sorpresas.

← Anterior
Cómo nació x86: por qué el 8086 se convirtió en un estándar «accidental» durante décadas
Siguiente →
Ubuntu 24.04: Fail2ban no está bloqueando nada — flujo rápido de verificación

Deja un comentario