Cuándo
24 de agosto de 2026, dentro de una racha de 4 hotfixes seguidos el mismo día sobre el bucle SNMP del Local Agent (2.21.1 → 2.21.2 → 2.21.3 → 2.21.4, en unas 3 horas). Este es el cuarto y último: revierte lo que hizo el hotfix anterior (2.21.3, “el motor SNMP se cura solo”, v1.83.3) pocos minutos después de publicarlo.
Síntomas visibles
Tras publicar 2.21.3 —que recreaba el motor pysnmp al detectar 5 cuelgues SNMP seguidos, asumiendo el motor compartido corrupto—, la verificación en el Agente del CCIB (un site con muchos puntos de acceso) mostró 23 recreaciones del motor en 5 minutos con las peticiones colgándose exactamente igual que antes del parche. Cada recreación además borraba la línea base de ancho de banda (que solo tiene una muestra), dejando ese gráfico en blanco.
Causa raíz
El motor SNMP nunca estuvo corrupto. El CCIB tiene 123 puntos de acceso monitorizados y solo 48 responden — el número de siempre, no una regresión. Los ~75 restantes están apagados también para SNMP (no solo para ping), y con ellos pysnmp no devuelve su propio timeout de 5 segundos: la petición se queda colgada hasta que el Agente la corta por su cuenta (SNMP_HARD_TIMEOUT, entonces en 10 s). Recrear el motor no resolvía nada porque el problema no estaba en el motor, sino en que cada uno de esos 75 hosts cuesta el tope completo — y 2.21.3 malinterpretó ese patrón como “motor corrupto”.
Fix aplicado
Commit b2e4540547ffe4bea0cd96d9dee33eca789b5a17 (PR #433, Agent 2.21.4, SaaS v1.83.4):
- Se retira por completo la recreación automática del motor SNMP añadida en 2.21.3 (
SNMP_HANG_RECREATE_THRESHOLDy la lógica enSentinelScheduler.note_snmp_hang,terminal/agent/sentinel/scheduler.py). Un cuelgue ahora solo cuenta como fallo del target. - El cortacircuitos de SNMP (
_circuit_breaker) ya existente es quien abre esos targets a los 5 fallos — su trabajo original, sin la capa de “autocuración” de por medio. SNMP_HARD_TIMEOUTbaja de 10 a 7 segundos (terminal/agent/config.py) — timeout real depysnmp(5 s) más margen, para que las primeras vueltas tras actualizar (con los 75 hosts muertos aún sin abrir por el cortacircuitos) no tarden minutos.- El test
TestHangsNeverRecreateEngine(tests/agent/test_snmp_hard_timeout_and_prune.py) sustituye aTestEngineSelfHeal: verifica que 12 cuelgues seguidos NO disparanrecreate_snmp_enginey queengine_recreationsse queda a 0.
Lecciones
- Un síntoma que encaja con un fallo conocido (motor
pysnmpcompartido que se corrompe, ya visto en el incidente que motivó 2.21.1) puede tener otra causa: aquí era simplemente volumen de hosts muertos, no corrupción. - El propio mecanismo de verificación de 2.21.3 (mirar
/sentinel/statustras desplegar) fue lo que destapó el error a los pocos minutos — las 23 recreaciones en 5 min sin que los cuelgues bajaran era la prueba de que la hipótesis estaba equivocada. - Recrear un recurso compartido como respuesta a un fallo tiene coste (aquí, perder la única muestra de la línea base de ancho de banda), y ese coste hay que pesarlo contra la certeza real del diagnóstico antes de aplicarlo.
Preventivos futuros
- Queda abierto (documentado en el CHANGELOG como “límite honesto”) por qué
pysnmpno honra su propio timeout ante hosts sin respuesta ARP — candidato:retries=0combinado con una respuesta ICMP unreachable que el dispatcher asíncrono no traduce en error. No se investiga en este hotfix. - El indicador de salud a vigilar tras cualquier cambio en esta área:
engine_recreationsen/sentinel/statusdebe quedarse a 0, ycyclesdebe seguir creciendo sin parar.
Véase también
- [[incident—20260717—monitoring-targets-stuck-down]]
- [[incident—20260722—flapping-ws-redis-py-8]]
- [[feature—monitoring—sonda-tcp]]
- [[feature—monitoring—tcp-probe-suppression-v1634]]
- [[crearack-tech—agents—dev-terminal]]