Tres incidentes resueltos en la sesión del 2026-08-12/13: 504 intermitente por QUIC inestable en cloudflared, precios null por falta de region_id en el Store API de Medusa v2 (se descarta la hipótesis inicial de regiones COP duplicadas con evidencia directa en Postgres), e imágenes en blanco por un proxy host mal configurado en Nginx Proxy Manager para media.cruzcloud.net. Se agregan también dos notas de referencia en known-issues.md: la topología Cloudflare Tunnel -> NPM -> k3d, y el requisito de region_id explícito en StoreGetProductsParams.
53 lines
3.4 KiB
Markdown
53 lines
3.4 KiB
Markdown
# Incidente: 504 Gateway Timeout intermitente en gitea.cruzcloud.net (túnel QUIC inestable) (2026-08)
|
||
|
||
**Ventana del incidente:** intermitente durante varias horas, 2026-08
|
||
**Servicio afectado:** `cloudflared` (túnel de Cloudflare, app nativa de ZimaOS, modo red Host) — afecta a todos los subdominios servidos por el mismo túnel (`gitea.cruzcloud.net`, `commerce.cruzcloud.net`, `shop.cruzcloud.net`, `media.cruzcloud.net`, Immich, Argo CD, Memos, etc.)
|
||
**Impacto:** 504 Gateway Timeout intermitente en peticiones HTTP a cualquier host detrás del túnel, sin patrón evidente de horario ni de carga.
|
||
|
||
## Síntoma
|
||
|
||
`gitea.cruzcloud.net` devolvía `504 Gateway Timeout` de forma intermitente. El mismo síntoma se observaba en otros hosts servidos por el mismo túnel (Immich, Argo CD, Memos), lo que apuntaba a una causa compartida a nivel de túnel, no de una app individual.
|
||
|
||
## Diagnóstico
|
||
|
||
```
|
||
docker logs -f cloudflared 2>&1 | grep -i -E "connIndex|protocol|retry"
|
||
```
|
||
|
||
Reveló un patrón sostenido durante horas: la conexión `connIndex=2` (de las 4 conexiones que `cloudflared` mantiene hacia el edge de Cloudflare) sufría fallos recurrentes de "control stream" cada 2-6 minutos, reconectándose en loop:
|
||
|
||
```
|
||
control stream encountered a failure while serving
|
||
Retrying connection in up to 1m4s
|
||
```
|
||
|
||
Cuando una petición HTTP coincidía con el instante exacto de una de esas caídas de `connIndex=2`, el cliente recibía el 504.
|
||
|
||
## Causa raíz
|
||
|
||
El contenedor `cloudflared` (imagen oficial `cloudflare/cloudflared:latest`) usaba **QUIC (UDP)** como protocolo de transporte por defecto para sus 4 conexiones hacia el edge de Cloudflare. Una de esas conexiones presentaba fallos de control stream recurrentes durante horas.
|
||
|
||
Causa de fondo probable: inestabilidad de UDP/QUIC en la red local (NAT/firewall doméstico). QUIC es más sensible que TCP/HTTP2 a NATs agresivos o middleboxes que no manejan bien tráfico UDP de larga vida — un patrón común en redes domésticas, a diferencia de datacenters con NAT dedicado para este tipo de tráfico.
|
||
|
||
## Fix aplicado
|
||
|
||
Se agregó la variable de entorno `TUNNEL_TRANSPORT_PROTOCOL=http2` en la configuración del contenedor `cloudflared` desde la app de ZimaOS (sección Ambiente → variables), forzando HTTP/2 sobre TCP en vez de QUIC/UDP.
|
||
|
||
Tras reiniciar el contenedor, el precheck de `cloudflared` confirmó:
|
||
|
||
```
|
||
Environment is healthy. cloudflared will use 'http2' as primary protocol.
|
||
```
|
||
|
||
y las 4 conexiones pasaron a `protocol=http2`.
|
||
|
||
## Validación
|
||
|
||
Curl en loop contra `gitea.cruzcloud.net` tras el cambio: latencia estable ~0.37–0.4s sostenida por 24+ minutos sin un solo 504.
|
||
|
||
## Nota — degradación puntual no relacionada, pendiente de vigilar
|
||
|
||
Durante la ventana de validación se observó una ventana breve de latencia alta (hasta 39s) y algunos `502`/`530`, coincidiendo con una ejecución pesada de Gitea Actions (build/deploy de Medusa) en el mismo host. Esto es contención de recursos local (CPU/IO del host compitiendo entre el runner de Actions y el resto de los servicios), **no relacionado al fix de protocolo del túnel** — no se reabrió como parte de este incidente.
|
||
|
||
**Pendiente:** vigilar si estas ventanas de degradación coinciden sistemáticamente con builds/deploys de Gitea Actions. Si es recurrente, considerar mover el runner (`gitea-runner`) a otro host o limitarle recursos (CPU/memoria) para evitar que compita con el resto de las apps del NAS.
|