Tu sitio funcionaba bien. Luego actualizaste “un pequeño plugin”. Ahora estás frente a un error 500, una pantalla blanca o un wp-admin que se niega a cargar. El negocio quiere un ETA. Tu pager está sonando otra vez. Bienvenido.
Esta es una guía de recuperación para quienes necesitan que el sitio vuelva ahora, sin empeorar el post-mortem. Desactivaremos el plugin roto desde el sistema de archivos (FTP/SSH), confirmaremos qué ocurrió exactamente y pondremos barreras para que la próxima actualización no se convierta en un incidente.
Guía de diagnóstico rápido (primeros 10 minutos)
Estás tratando de responder una pregunta: ¿El sitio está caído porque PHP se bloquea, porque la base de datos es inalcanzable, o porque WordPress quedó en un estado malo (modo mantenimiento, opciones autoload, conflicto de plugins)?
No “pruebes arreglos aleatorios”. Así es como terminas con un sitio que funciona y sin saber por qué, que es una manera elegante de decir “incidente repetido”. Aquí está el orden que encuentra el cuello de botella rápidamente.
1) Confirma el modo de fallo desde afuera
- Si ves HTTP 500/502/503: sospecha errores fatales de PHP, timeouts upstream o modo mantenimiento.
- Si ves una pantalla blanca (sin HTML): fatal clásico de PHP o memoria agotada.
- Si wp-admin carga pero las acciones fallan: escrituras en la base de datos, permisos, problemas de nonce/sesión o un hook de plugin específico.
- Si solo falla la página principal: tema, capa de caché, plugin de maquetador o una ruta específica.
2) Revisa los registros del servidor antes de tocar WordPress
Los logs te dicen si estás ante un error fatal de un plugin, un problema de permisos o algo de nivel inferior (PHP-FPM caído, disco lleno). Si no encuentras logs con rapidez, aún puedes proceder a desactivar plugins vía sistema de archivos como instrumento contundente; pero es mejor cuando puedes nombrar al responsable.
3) Desactiva el plugin sospechoso (primero uno solo)
Si sabes qué plugin se actualizó, desactívalo renombrando su carpeta. Si no lo sabes, desactiva todos los plugins renombrando el directorio plugins. Recupera el sitio y luego afina el diagnóstico.
4) Limpia las cachés y confirma que PHP está sano
Objeto de caché, caché de página, CDN y opcache de PHP pueden servir comportamiento roto después de “arreglar” los archivos. Confirma con una petición directa, revisa los logs otra vez y solo entonces declara victoria.
5) Estabiliza antes de volver a habilitar nada
Una vez que el sitio vuelve, tu trabajo cambia: preserva evidencia (logs), evita actualizaciones automáticas que re-rompan las cosas y crea una vía segura para reintroducir el plugin o hacer rollback.
Una cita para tener a mano: Idea parafraseada — Gene Kranz: el fracaso no es aceptable; los equipos triunfan por la preparación disciplinada y la ejecución bajo presión.
Qué suele romperse cuando un plugin “rompe WordPress”
Los plugins de WordPress no son “extensiones” en el sentido amable. Son fragmentos de PHP que se ejecutan dentro del ciclo de petición con los mismos privilegios que el core. Un plugin puede:
- Provocar un error fatal (error de sintaxis, clase/función faltante, incompatibilidad de versión de PHP).
- Agotar memoria o tiempos de ejecución (bucles infinitos, opciones autoload enormes, consultas costosas).
- Romper sesiones de administración (cookies, nonces, redirecciones).
- Corromper reglas de reescritura o emitir encabezados inválidos.
- Disparar cambios de esquema de base de datos que se apliquen parcialmente.
Dos “gotchas” principales que hacen que los incidentes por plugins parezcan aleatorios:
- Opciones autoload: Algunos plugins almacenan datos grandes en
wp_optionsconautoload = 'yes'. Eso significa que WordPress los carga en memoria en muchas peticiones. Todo se vuelve lento y luego falla. - Orden de carga y hooks: Tu sitio puede romperse solo para usuarios autenticados, o solo en cron, porque ahí es donde corre el hook del plugin.
Broma #1: Una actualización de plugin es como “solo un cambio rápido” un viernes—técnicamente posible, espiritualmente poco aconsejable.
Camino de recuperación A: desactivar el plugin via FTP / gestor de archivos
Si tienes FTP o el gestor de archivos del hosting pero no shell, aún puedes recuperarte rápido. El objetivo es que WordPress deje de cargar el código del plugin. WordPress carga plugins escaneando directorios bajo wp-content/plugins. Si el nombre del directorio cambia, WordPress lo considera ausente y lo desactiva.
Desactivar un plugin (preferido)
- Conéctate via FTP / abre el gestor de archivos del hosting.
- Navega a:
public_html/wp-content/plugins/(tu raíz puede variar). - Encuentra la carpeta del plugin que se actualizó o que te parece sospechosa.
- Renómbrala, por ejemplo:
elementor→elementor.disabledwoocommerce→woocommerce.off
- Recarga el sitio y wp-admin.
Qué hace esto: WordPress ve que el plugin falta y lo marca como desactivado. Es tosco, pero funciona incluso cuando PHP está en llamas.
Desactivar todos los plugins (opción nuclear, pero rápida)
- Ve a
wp-content/. - Renombra
plugins→plugins.disabled. - Recarga. Si el sitio vuelve, has demostrado que el incidente está relacionado con plugins.
- Crea un nuevo directorio vacío
plugins(WordPress lo espera), luego mueve los plugins de vuelta uno por uno.
Cuando la recuperación por FTP falla
FTP está bien hasta que los permisos, la propiedad o la caché se ponen raros. Si renombrar no se mantiene, o los cambios revierten, probablemente estés tratando con:
- un sistema de despliegue que sobrescribe archivos
- sistema de archivos de solo lectura / problemas de permisos
- múltiples copias de WordPress y estás editando la equivocada
En ese punto necesitas SSH o el soporte del proveedor para confirmar el document root real y la propiedad de archivos.
Camino de recuperación B: desactivar el plugin por SSH (y por qué es mejor)
SSH convierte la recuperación de “clic y rezar” a “observar, cambiar, verificar”. Puedes tailear logs, confirmar rutas y revertir limpiamente.
El plan mínimo viable por SSH
- Encuentra el directorio raíz de WordPress.
- Confirma el directorio de plugins y el nombre de la carpeta del plugin.
- Renombra la carpeta del plugin (o el directorio
plugins) para desactivar. - Revisa los logs para confirmar que el error fatal cesó.
- Recarga con
curly verifica el estado HTTP y el contenido.
Por qué renombrar funciona de forma fiable
WordPress almacena los “plugins activos” en la base de datos, pero aun así verifica si el archivo del plugin existe. Si la carpeta no está, WordPress no puede incluirla y la desactiva en la siguiente carga. Renombrar es efectivamente una “brecha de aire” entre WordPress y el PHP roto.
Camino de recuperación C: WP-CLI desactivar (la opción más limpia)
Si WP-CLI está instalado y puedes ejecutarlo como el usuario correcto, esta es la opción más controlada. Actualiza el estado interno de WordPress en vez de depender de trucos en el sistema de archivos. Pero si PHP está fatalmente roto antes de que WP-CLI pueda bootstrapear, renombrar sigue ganando.
Verificar la recuperación como un SRE (no confíes en la página principal)
Recuperar la página principal está bien. No es “recuperado”. La verificación real comprueba:
- wp-admin carga y el inicio de sesión funciona
- una petición que evita caché devuelve 200
- los logs de error dejan de mostrar fatales
- los formularios de contacto/checkout aún envían
- cron no está generando errores en masa
Además: toma una instantánea (backup) después de estabilizar. No antes. Un backup del estado roto es un souvenir, no una solución.
Tareas prácticas con comandos: qué significa la salida y qué hacer después
Abajo hay tareas prácticas que puedes ejecutar por SSH. Cada una incluye (1) el comando, (2) salida de ejemplo, (3) qué significa la salida y (4) la decisión que tomas después.
Task 1: Confirmar que estás en la raíz correcta de WordPress
cr0x@server:~$ cd /var/www/example.com/public_html && ls -la
total 248
drwxr-xr-x 7 www-data www-data 4096 Dec 27 09:10 .
drwxr-xr-x 3 root root 4096 Dec 20 11:02 ..
-rw-r--r-- 1 www-data www-data 420 Nov 3 10:21 index.php
-rw-r--r-- 1 www-data www-data 19935 Nov 3 10:21 wp-blog-header.php
-rw-r--r-- 1 www-data www-data 3516 Nov 3 10:21 wp-config.php
drwxr-xr-x 9 www-data www-data 4096 Dec 10 12:01 wp-content
drwxr-xr-x 8 www-data www-data 4096 Nov 3 10:21 wp-admin
drwxr-xr-x 25 www-data www-data 4096 Nov 3 10:21 wp-includes
Significado: La presencia de wp-config.php, wp-admin y wp-includes sugiere fuertemente que estás en el lugar correcto.
Decisión: Continúa. Si no ves estos archivos, detente y encuentra la raíz real. Desactivar plugins en el directorio equivocado es la forma en que la gente “no arregla” nada durante una hora.
Task 2: Identificar los directorios de plugins modificados recientemente (a menudo el culpable)
cr0x@server:~$ cd /var/www/example.com/public_html/wp-content/plugins && ls -lt | head
total 64
drwxr-xr-x 12 www-data www-data 4096 Dec 27 09:02 some-plugin
drwxr-xr-x 10 www-data www-data 4096 Dec 27 08:58 cache-tool
drwxr-xr-x 8 www-data www-data 4096 Dec 10 12:00 seo-pack
drwxr-xr-x 15 www-data www-data 4096 Dec 1 15:22 woocommerce
Significado: Los plugins actualizados recientemente suben al tope. Ese timestamp a menudo coincide con la caída.
Decisión: Empieza desactivando el plugin modificado más recientemente que coincida con la ventana de cambio.
Task 3: Desactivar un solo plugin renombrando su directorio
cr0x@server:~$ mv /var/www/example.com/public_html/wp-content/plugins/some-plugin /var/www/example.com/public_html/wp-content/plugins/some-plugin.disabled
Significado: No producir salida es normal para mv. Si da error, verás problemas de permisos o rutas faltantes.
Decisión: Si el sitio vuelve, has aislado al culpable. Si no, pasa a desactivar todos los plugins o revisa logs para otro modo de fallo.
Task 4: Desactivar todos los plugins renombrando el directorio plugins
cr0x@server:~$ cd /var/www/example.com/public_html/wp-content && mv plugins plugins.disabled && mkdir plugins
Significado: WordPress tratará todos los plugins como ausentes; crear un plugins vacío evita advertencias y mantiene saneadas futuras instalaciones.
Decisión: Si el sitio vuelve ahora, sabes que es por plugins. Si sigue caído, enfócate en PHP, base de datos o servidor web.
Task 5: Curl al sitio y confirmar estado sin la caché del navegador
cr0x@server:~$ curl -sS -D- -o /dev/null https://example.com/ | head -n 12
HTTP/2 200
date: Sat, 27 Dec 2025 09:12:10 GMT
content-type: text/html; charset=UTF-8
cache-control: no-cache, must-revalidate, max-age=0
server: nginx
Significado: HTTP 200 sugiere que la capa web y PHP responden. Los encabezados indican si hay caché en juego.
Decisión: Si sigues viendo 500/502/503, inspecciona logs inmediatamente. Si es 200 pero el contenido es incorrecto, sospecha caché o fallos parciales.
Task 6: Tail de logs de PHP-FPM o errores web para capturar la línea del fatal
cr0x@server:~$ sudo tail -n 60 /var/log/nginx/error.log
2025/12/27 09:03:44 [error] 22110#22110: *881 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined function some_plugin_init() in /var/www/example.com/public_html/wp-content/plugins/some-plugin/some-plugin.php:42
Stack trace:
#0 /var/www/example.com/public_html/wp-settings.php(453): include_once()
#1 /var/www/example.com/public_html/wp-config.php(92): require_once('...')
#2 /var/www/example.com/public_html/wp-load.php(50): require_once('...')
#3 /var/www/example.com/public_html/wp-blog-header.php(13): require_once('...')
#4 /var/www/example.com/public_html/index.php(17): require('...')
#5 {main}
thrown" while reading response header from upstream, client: 203.0.113.10, server: example.com, request: "GET / HTTP/2.0"
Significado: Este es el arma humeante: función indefinida en un archivo de plugin. A menudo causado por una dependencia faltante, actualización parcial o incompatibilidad de versión de PHP.
Decisión: Desactiva ese plugin (renombra la carpeta) y mantenlo deshabilitado hasta que puedas revertir o arreglar el entorno.
Task 7: Confirmar espacio en disco (discos llenos causan fallos “aleatorios” de PHP)
cr0x@server:~$ df -h /var/www
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 39G 420M 99% /
Significado: 99% usado es territorio de incidente. Las actualizaciones pueden fallar a mitad de extracción, los logs no pueden escribirse, las sesiones PHP no se guardan. Todo se pone inestable.
Decisión: Libera espacio primero. Si no, “arreglar” el plugin y volver a caer cinco minutos después es probable.
Task 8: Buscar un archivo de modo mantenimiento atascado
cr0x@server:~$ ls -la /var/www/example.com/public_html/.maintenance
-rw-r--r-- 1 www-data www-data 55 Dec 27 09:01 /var/www/example.com/public_html/.maintenance
Significado: WordPress deja .maintenance durante actualizaciones. Si la actualización se cae, el archivo puede quedar y mantener el sitio en modo mantenimiento.
Decisión: Elíminalo si no estás actualizando activamente.
cr0x@server:~$ rm -f /var/www/example.com/public_html/.maintenance
Task 9: Validar versión de PHP frente a los requisitos del plugin
cr0x@server:~$ php -v
PHP 7.4.33 (cli) (built: Nov 8 2024 10:14:11) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
Significado: Muchos plugins modernos requieren PHP 8.x. Si una actualización asumió PHP 8 y estás en 7.4, los errores fatales pueden ocurrir de inmediato.
Decisión: Si el plugin requiere una versión más nueva de PHP, mantenlo deshabilitado y planifica una actualización ordenada de PHP (o revierte la versión del plugin). No “actualices PHP rápido” durante el incidente a menos que quieras una noche larga.
Task 10: Comprobar propiedad/permisos de archivos (las actualizaciones fallidas suelen dejar archivos root)
cr0x@server:~$ find /var/www/example.com/public_html/wp-content/plugins -maxdepth 2 -type f -name '*.php' -printf '%u %g %p\n' | head
root root /var/www/example.com/public_html/wp-content/plugins/some-plugin/some-plugin.php
www-data www-data /var/www/example.com/public_html/wp-content/plugins/seo-pack/seo-pack.php
Significado: Un archivo de plugin propiedad de root en un árbol usualmente propiedad de www-data sugiere que alguien ejecutó una actualización como root (o una herramienta de extracción lo hizo). WordPress puede fallar al sobrescribir o limpiar después.
Decisión: Arregla la propiedad del plugin afectado o de todo el árbol (con cuidado), luego vuelve a ejecutar actualizaciones mediante el mecanismo correcto.
cr0x@server:~$ sudo chown -R www-data:www-data /var/www/example.com/public_html/wp-content/plugins/some-plugin.disabled
Task 11: Confirmar conectividad a la base de datos desde el config de WordPress (sin volcar secretos)
cr0x@server:~$ grep -E "DB_NAME|DB_USER|DB_HOST" /var/www/example.com/public_html/wp-config.php
define( 'DB_NAME', 'wpdb' );
define( 'DB_USER', 'wpuser' );
define( 'DB_HOST', '127.0.0.1' );
Significado: Estás verificando el host de BD y que estás viendo la configuración correcta para este sitio.
Decisión: Si el síntoma parece fallo de BD (“Error establishing a database connection”), prueba el servicio de BD a continuación.
Task 12: Comprobar salud de MySQL/MariaDB en el host
cr0x@server:~$ sudo systemctl status mariadb --no-pager | sed -n '1,12p'
● mariadb.service - MariaDB 10.6.16 database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2025-12-27 08:10:03 UTC; 1h 2min ago
Docs: man:mariadbd(8)
https://mariadb.com/kb/en/library/systemd/
Main PID: 982 (mariadbd)
Status: "Taking your SQL requests now..."
Significado: La BD está en ejecución. Esto no prueba que las consultas sean rápidas, pero elimina “BD caída” de la lista.
Decisión: Si el sitio sigue roto, vuelve a enfocarte en errores de PHP, plugins y capas de caché.
Task 13: Encontrar el error fatal del plugin en los logs de PHP (si están separados)
cr0x@server:~$ sudo tail -n 60 /var/log/php8.1-fpm.log
[27-Dec-2025 09:03:44] WARNING: [pool www] child 22134 said into stderr: "PHP Fatal error: Uncaught Error: Call to undefined function some_plugin_init() in /var/www/example.com/public_html/wp-content/plugins/some-plugin/some-plugin.php:42"
Significado: Confirma que el error fatal está a nivel PHP-FPM, no una conjetura de Nginx.
Decisión: Mantén el plugin deshabilitado y soluciona la incompatibilidad subyacente (versión del plugin, dependencia, versión de PHP).
Task 14: Verificar que el sitio responde localmente (evita problemas de CDN/DNS)
cr0x@server:~$ curl -sS -H 'Host: example.com' http://127.0.0.1/ | head -n 5
<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
Significado: El servidor origen renderiza HTML localmente. Si los usuarios externos aún ven errores, el problema podría ser caché de CDN, reglas WAF o health checks del balanceador.
Decisión: Si local funciona y externo falla, cambia la atención a capas superiores: CDN, reverse proxy, terminación TLS, firewall.
Task 15: Usar WP-CLI para listar plugins (si es posible)
cr0x@server:~$ cd /var/www/example.com/public_html && sudo -u www-data wp plugin list
+-------------------+----------+-----------+---------+
| name | status | update | version |
+-------------------+----------+-----------+---------+
| seo-pack | inactive | none | 3.2.1 |
| cache-tool | inactive | available | 2.9.0 |
| some-plugin | inactive | none | 1.4.0 |
+-------------------+----------+-----------+---------+
Significado: Puedes ver qué está activo/inactivo y qué tiene actualizaciones pendientes. Tras renombrar una carpeta, WP-CLI puede mostrar el plugin como faltante o inactivo según el estado.
Decisión: Usa WP-CLI para reactivar cuidadosamente más tarde, un plugin a la vez, vigilando los logs.
Task 16: Desactivar un plugin limpiamente con WP-CLI
cr0x@server:~$ cd /var/www/example.com/public_html && sudo -u www-data wp plugin deactivate some-plugin
Plugin 'some-plugin' deactivated.
Success: Deactivated 1 of 1 plugins.
Significado: WordPress ahora concuerda en que el plugin está inactivo. Esto es más limpio que renombrar directorios cuando puedes ejecutarlo.
Decisión: Si la desactivación tiene éxito y el sitio se recupera, puedes restaurar el nombre del directorio del plugin (si lo renombraste) sin reactivarlo.
Task 17: Buscar opciones autoload desbocadas (causa común de “todo se volvió lento”)
cr0x@server:~$ cd /var/www/example.com/public_html && sudo -u www-data wp db query "SELECT option_name, LENGTH(option_value) AS bytes FROM wp_options WHERE autoload='yes' ORDER BY bytes DESC LIMIT 10;"
+---------------------------+--------+
| option_name | bytes |
+---------------------------+--------+
| some_plugin_cache_blob | 524288 |
| rewrite_rules | 182944 |
| wp_user_roles | 32768 |
+---------------------------+--------+
Significado: Un blob autoload de medio megabyte es sospechoso. Infla la memoria y ralentiza cada petición.
Decisión: Mantén el plugin deshabilitado; considera eliminar o quitar el autoload de la opción tras hacer backup y revisar con cuidado.
Task 18: Comprobar límite de memoria PHP rápidamente (síntoma: pantalla blanca o “Allowed memory size exhausted”)
cr0x@server:~$ php -r 'echo ini_get("memory_limit").PHP_EOL;'
128M
Significado: 128M puede ser justo para plugins pesados/maquetadores. Pero aumentar la memoria es un parche, no un diagnóstico.
Decisión: Si los logs muestran agotamiento de memoria, puedes aumentar temporalmente la memoria para restaurar el servicio y luego arreglar el comportamiento del plugin o eliminarlo.
Errores comunes: síntomas → causa raíz → solución
Esta sección es donde el tú del futuro evita un incidente repetido. No son teóricos; ocurren porque WordPress es una mezcla de buenas intenciones y includes de PHP.
1) Síntoma: “Renombré la carpeta del plugin pero nada cambió”
- Causa raíz: Editaste la instancia de WordPress equivocada (docroot incorrecto), o un job de despliegue restauró la carpeta, o el sitio se sirve desde otro nodo.
- Solución: Confirma el docroot (Task 1), confirma con curl local (Task 14) y verifica si estás en un entorno con balanceo de carga. Aplica cambios en el origen real o en todos los nodos.
2) Síntoma: “El sitio muestra modo mantenimiento para siempre”
- Causa raíz: Archivo
.maintenanceatascado tras una actualización fallida. - Solución: Elimina
.maintenance(Task 8). Luego investiga por qué falló la actualización (disco lleno, permisos, timeout).
3) Síntoma: HTTP 502 Bad Gateway después de una actualización de plugin
- Causa raíz: PHP-FPM se está bloqueando o agotando por errores fatales, agotamiento de memoria o peticiones largas disparadas por el plugin.
- Solución: Revisa el log de Nginx y el log de PHP-FPM (Tasks 6, 13). Desactiva el plugin; luego aborda recursos PHP o el problema de código.
4) Síntoma: wp-admin carga, pero al guardar settings devuelve 500
- Causa raíz: Hooks del plugin en peticiones POST del admin que fatalan solo en ese camino; o WAF bloquea payloads específicos; o PHP max input vars/tiempos.
- Solución: Tail de logs mientras reproduces. Desactiva el plugin sospechoso y vuelve a probar. Si sigue fallando, revisa logs del WAF y settings de PHP.
5) Síntoma: Todo está “up” pero terriblemente lento tras actualizar un plugin
- Causa raíz: Opciones autoload hinchadas, consultas DB costosas o thrash del objeto de caché.
- Solución: Inspecciona tamaños de autoload (Task 17), revisa logs de consultas lentas si existen y desactiva temporalmente plugins de caché para comparar comportamiento.
6) Síntoma: Solo los usuarios autenticados ven una pantalla blanca
- Causa raíz: El plugin corre solo para admin/toolbar o hooks específicos de usuario; el error fatal está oculto por la configuración de display_errors.
- Solución: Tail de logs mientras accedes a wp-admin. Desactiva plugins de admin primero (security, editores, maquetadores).
7) Síntoma: El plugin no se actualiza, o las actualizaciones “suceden” pero se revierten
- Causa raíz: Propiedad/permisos incorrectos, archivos inmutables o un sistema CI/deploy que sobrescribe el árbol.
- Solución: Revisa la propiedad (Task 10). Confirma si los archivos de WordPress están gestionados por Git/despliegue. Decide una única autoridad: o el sistema de despliegue o el actualizador de WP, no ambos.
8) Síntoma: Lo arreglé y volvió a romperse minutos después
- Causa raíz: Auto-updates reaplicó el cambio, un cron reactivó algo o la caché se calentó con código roto desde otro nodo.
- Solución: Desactiva actualizaciones automáticas temporalmente, revisa eventos cron y asegura que todos los nodos compartan el mismo estado de plugins.
Tres microhistorias corporativas desde las trincheras de incidentes
Microhistoria 1: El incidente causado por una suposición equivocada
Una compañía mediana tenía un sitio de marketing WordPress detrás de un CDN y un balanceador gestionado. El sitio “se cayó” justo después de una actualización de plugin. El ingeniero on-call hizo lo estándar: SSH al servidor, renombró la carpeta del plugin culpable y refrescó el navegador.
Siguió caído. Mismo 500.
La suposición equivocada fue sutil: asumieron que había un origin. Había dos. Uno era el nodo viejo que quedó después de una migración, aún registrado en el pool del balanceador. El plugin se deshabilitó en el nodo en el que iniciaron sesión (porque recordaban ese hostname), pero el tráfico seguía yendo al otro nodo con el código roto.
Lo demostraron haciendo curl a cada nodo directamente con un header Host. Un nodo devolvió 200, el otro 500. Una vez deshabilitaron el plugin en el segundo nodo, el incidente se resolvió de inmediato.
La corrección post-incidente fue aburrida y efectiva: eliminar orígenes obsoletos del pool y documentar el inventario autoritativo. También: deja de confiar en “el hostname que recuerdas”. Producción no respeta tu memoria.
Microhistoria 2: La optimización que salió mal
Otra organización tenía un sitio WordPress de alto tráfico y quería páginas más rápidas. Alguien instaló un plugin de caché y puso ajustes agresivos: minificación HTML, combinar scripts, deferir todo y habilitar caching de objetos respaldado por un daemon local. Mejoró los benchmarks sintéticos.
Luego llegó una actualización de plugin. El sitio empezó a lanzar 502 intermitentes. No consistentemente—suficiente para volverlo enloquecedor. El plugin no era toda la historia: la capa de caché estaba almacenando respuestas parciales de error y sirviéndolas esporádicamente. Mientras tanto, el daemon de caché de objetos se reiniciaba por presión de memoria, causando tormentas de peticiones mientras las cachés se recalientaban.
El equipo inicialmente intentó “optimizar más”: aumentar TTLs, añadir exclusiones, reiniciar servicios con más frecuencia. Eso empeoró todo, porque cada reinicio amplificaba la multitud de peticiones sin caché golpeando PHP y la BD.
La solución fue humillante y simple: desactivar temporalmente el plugin de caché, estabilizar y luego reintroducir caché con ajustes conservadores y verdadera observabilidad. El trabajo de rendimiento sin medición es solo superstición con mejor presentación.
Microhistoria 3: La práctica aburrida pero correcta que salvó el día
Una compañía del sector financiero ejecutaba WordPress en contenedores. No era sofisticado, solo disciplinado: despliegues eran imágenes inmutables, las actualizaciones de plugins pasaban por staging primero y producción solo cambiaba mediante pipeline. También mantenían retención corta de backups nocturnos de BD e instantáneas del sistema de archivos.
Una mañana, una actualización de plugin pasó staging pero rompió producción—porque producción tenía una versión menor de PHP distinta debido a una imagen base fijada hace tiempo. El plugin llamaba a una característica de PHP no disponible en prod. Error fatal instantáneo.
En vez de debuggear en vivo en producción, ejecutaron el runbook practicado: revertir la imagen del contenedor a la conocida buena, restaurar servicio y luego comparar versiones de PHP y requisitos del plugin en un estado más tranquilo. El impacto comercial fue mínimo porque el rollback no fue un acto heroico; fue martes.
La corrección a largo plazo: alinear imágenes base de staging/producción y añadir una comprobación en pipeline que asegure paridad de versión PHP. La práctica aburrida—entornos consistentes y rollback ensayado—fue lo que realmente hizo el trabajo.
Hechos y contexto histórico (breve, útil y un poco sobrio)
- Hecho 1: WordPress empezó en 2003 como un fork de b2/cafelog, y su arquitectura de plugins creció con el ecosistema—poderosa, pero no aislada.
- Hecho 2: Los plugins ejecutan PHP en proceso; no hay un límite de aislamiento como en el modelo de extensiones de navegador. Un plugin puede romper el core con un solo error fatal.
- Hecho 3: La “Pantalla Blanca de la Muerte” se volvió meme porque los fatales de PHP a menudo producían salida en blanco cuando display_errors estaba apagado.
- Hecho 4: Las actualizaciones automáticas en background para parches de seguridad se introdujeron para reducir el retraso de parches, pero también aumentaron la posibilidad de cambios no supervisados que interactúan mal con plugins.
- Hecho 5: El archivo
.maintenanceexiste específicamente para prevenir estados inconsistentes durante actualizaciones, pero puede dejarte varado si la actualización se cae. - Hecho 6: Muchas caídas tras “actualizaciones de plugin” son en realidad extracciones parciales por espacio en disco bajo o problemas de permisos, dejando clases PHP faltantes.
- Hecho 7: PHP 7.4 llegó al end-of-life en 2022, y los plugins han ido elevando sus requisitos mínimos, convirtiendo stacks viejos en minas de tiempo.
- Hecho 8: WordPress guarda los “plugins activos” en la BD, pero aún verifica que los archivos existan en disco, por eso renombrar carpetas es un freno de emergencia tan fiable.
- Hecho 9: Un asesino de rendimiento sorprendentemente común es una opción autoload hinchada: se carga en muchas peticiones y penaliza todo por igual.
Listas de verificación / plan paso a paso
Checklist 1: “El sitio está caído ahora mismo” (estabiliza primero)
- Captura el síntoma: estado HTTP (200/500/502/503), mensaje de modo mantenimiento, pantalla blanca, wp-admin accesible o no.
- Revisa logs: log de errores del servidor web y log de PHP-FPM en busca de una línea fatal apuntando a un archivo de plugin.
- Desactiva el plugin probable: renombra su carpeta bajo
wp-content/plugins. - Si dudas, desactiva todos los plugins: renombra
pluginsaplugins.disabledy crea un directoriopluginsvacío. - Elimina modo mantenimiento atascado: borra
.maintenancesi está presente. - Verifica con curl: confirma HTTP 200 y HTML básico desde el origen.
- Confirma login en wp-admin: si el admin funciona, tu siguiente trabajo es una restauración controlada.
Checklist 2: Restauración controlada (no lo vuelvas a romper)
- Vuelve a habilitar plugins uno a la vez: mueve una carpeta de plugin de vuelta (o activa via WP-CLI), luego prueba y revisa logs.
- Vigila fallos ocultos: prueba un endpoint dinámico (checkout, formulario de contacto, búsqueda), no solo la página principal.
- Limpia cachés deliberadamente: caché de página, caché de objetos, caché CDN (en ese orden). Confirma primero que el origen es el correcto.
- Bloquea actualizaciones automáticas temporalmente: evita que el sistema reintroduzca la versión mala.
- Registra evidencia: guarda el stack trace del fatal y la versión del plugin; lo necesitarás para rollback o soporte del proveedor.
Checklist 3: Prevención (convierte el dolor en proceso)
- Mantén staging alineado con producción: misma versión de PHP, mismas extensiones, misma pila de caché.
- Backups restaurables: base de datos + uploads + código de plugins/temas, prueba de restauración, no solo “tenemos backups”.
- Control de cambios para plugins: programa actualizaciones, registra versiones y evita “auto-actualizar todo” a menos que tengas músculo de rollback.
- Observabilidad: centraliza logs, mantiene logs de errores legibles y alerta sobre picos de 5xx y fatales de PHP.
Broma #2: La forma más rápida de aprender internals de WordPress es un outage de plugins. La segunda más rápida es leer esto antes del outage.
Preguntas frecuentes
1) Si renombro la carpeta de un plugin, ¿pierdo la configuración del plugin?
Normalmente no. La mayoría de configuraciones del plugin viven en la base de datos. Renombrar solo impide que el código se cargue. Pero algunos plugins ejecutan rutinas de uninstall al desactivarse; renombrar evita eso, lo cual muchas veces es más seguro durante la recuperación.
2) ¿Y si wp-admin también está caído y no puedo iniciar sesión?
Eso es normal en fatales de plugin porque WordPress no puede bootstrapear. Usa la desactivación por sistema de archivos (renombrar carpeta del plugin o el directorio plugins) o WP-CLI si este puede bootstrapear.
3) ¿Debo borrar la carpeta del plugin?
No, renómbrala. Borrar destruye evidencia y complica el rollback. Renombrar es reversible y rápido.
4) ¿Puedo desactivar un plugin directamente desde la base de datos?
Puedes, editando la opción active_plugins, pero es una herramienta afilada. Si ya estás en SSH, renombrar la carpeta es más seguro y rápido bajo presión. Usa ediciones en BD solo cuando entiendas arrays serializados de PHP y tengas backup.
5) ¿Por qué desactivar todos los plugins a veces no arregla el sitio?
Porque el plugin no era el único fallo. Culpables comunes: .maintenance atascado, PHP-FPM caído, disco lleno, problemas de conexión a BD o fatales a nivel de tema. Desactivar plugins es una prueba, no una religión.
6) Desactivé el plugin pero el sitio sigue mostrando la página de error. ¿Ahora qué?
Revisa si estás viendo respuestas de error en caché (CDN/caché de página). Verifica localmente desde el origen con curl. Luego limpia cachés. También confirma que cambiaste el nodo correcto en un setup con balanceo de carga.
7) ¿Cómo averiguo qué plugin lo causó si no lo sé?
Ordena los directorios de plugins por tiempo de modificación (Task 2), luego tail de logs buscando el stack trace fatal (Task 6). Si aún no puedes identificarlo, desactiva todos los plugins y vuelve a habilitarlos uno a uno hasta que vuelva a romperse.
8) ¿WP-CLI siempre es seguro durante un outage?
Es seguro cuando lo ejecutas como el usuario correcto y puede bootstrapear WordPress. Si el fatal ocurre antes de que WP cargue, WP-CLI también puede fallar. Mantén el método de renombrar carpetas como tu fallback sin dependencias.
9) ¿Cuál es la diferencia entre un 500 y un 502 en este contexto?
500 a menudo significa que el servidor web obtuvo una respuesta pero hubo un error interno (o PHP emitió un fatal y el servidor lo mapeó). 502 suele significar que el proxy inverso no pudo obtener una respuesta válida de PHP-FPM upstream (crash, timeout, bad gateway). En la práctica: ambos te llevan a revisar logs.
10) ¿Debo aumentar el límite de memoria PHP para arreglarlo?
Sólo si los logs muestran agotamiento de memoria, y solo como estabilizador temporal. Si una actualización de plugin de repente necesita el doble de memoria, estás pagando por el bug de otro con tu presupuesto de servidor.
Conclusión: próximos pasos para evitar repetir el dolor
Para recuperar rápido: desactiva el plugin renombrando su carpeta (o todo el directorio plugins), elimina un archivo .maintenance atascado, verifica con curl y lee logs hasta que la línea del fatal tenga sentido. Luego vuelve a habilitar plugins uno a uno, con logs abiertos, no por intuición.
Próximos pasos que realmente mueven la aguja:
- Detén la ruleta de plugins sin supervisión: programa actualizaciones y exige un plan de rollback.
- Alinea staging con producción: la paridad de versiones de PHP evita la mentira de “funcionó en staging”.
- Mejora la observabilidad: logs centralizados y alertas de 5xx convierten misteriosos outages en incidentes cortos.
- Practica el rollback: el mejor momento para aprender procedimientos de restauración no es durante un outage que impacta ingresos.