Troubleshooting¶
Outgoing devuelve 202 queued cuando se esperaba 200 sent¶
Diagnóstico: la instancia está disconnected (probablemente reconectando tras un blip o un restart en curso). El outbox tomó el mensaje y lo entregará cuando vuelva.
curl -sS -H "Authorization: Bearer $TOK" \
http://qrsgen:3100/api/instances/whatsapp-main | jq '.state'
Si el state se mantiene en disconnected o connecting muchos
minutos, la sesión probablemente está logged_out server-side. Mira
el último events_webhook_url por un evento logged_out. Solución:
re-parear.
Mensajes outgoing siguen fallando con "Error al enviar" en el downstream¶
Causas frecuentes:
- Container down:
docker service ps qrsgen_qrsgen— ¿está running? - Webhook URL mal configurada: debe ser
http://qrsgen:3100/api/instances/<INSTANCE_NAME>/webhook(sustituye<INSTANCE_NAME>por el nombre real). - HMAC mismatch: si tienes
WEBHOOK_HMAC_SECRETset, comprueba que el orquestador firma con el mismo secret y manda el headerX-Qrsgen-Signature. - Firewall bloquea:
dmesg | grep QRSGEN-DROP— paquetes droppeados. Si ves drops al downstream, añade su CIDR al allowlist enfirewall.sh. - Sesión WhatsApp perdida:
GET /api/instances/<INSTANCE_NAME>→state: "disconnected". Re-parear.
Outbox queue llena (503 queue full)¶
Una instancia con MaxQueueDepth=200 lleno significa que está
disconnected hace mucho rato y nadie la rescató. Acción inmediata:
# Ver cuántos pending tiene
curl -sS -H "Authorization: Bearer $TOK" \
http://qrsgen:3100/api/instances/whatsapp-main/outbox
# Si la instancia está logged_out, reparear y/o limpiar la cola:
PG=$(docker ps --format '{{.Names}}' | grep ^postgres)
docker exec "$PG" psql -U postgres -d bridge -c "
UPDATE bridge_outgoing_queue SET status='expired'
WHERE instance='whatsapp-main' AND status='pending';"
"Instance X — sin conexión activa"¶
La instancia se creó pero la sesión nunca se estableció. Razón habitual:
el usuario no escaneó el QR a tiempo (~2 min de pairing). Vuelve a
ejecutar refresh-qr y avisa de escanear más rápido.
Backend reinicia pero los técnicos siguen viendo "Conexión perdida"¶
El grace period de Disconnected (60 s para unreachable + 2 min para
disconnected) probablemente se está agotando. Verifica:
journalctl -u qrsgen-firewall.service— ¿hay drops?docker service logs qrsgen_qrsgen --tail 100 | grep -E "connected|disconnected"— ¿reconecta cada instancia?- Si una NO reconecta: probablemente
logged_outdesde el servidor de WhatsApp. Necesita nuevo QR.
"Error al enviar" en mensajes posteados como nota privada¶
Esto NO es problema de qrsgen. Es el downstream intentando despachar un
msg private:true como outgoing al webhook del inbox. qrsgen lo rechaza
correctamente vía la safety net. El error visible en la UI es
cosmético — el mensaje sí está registrado en el downstream como
nota interna.
Ban-risk level: high en una instancia¶
Tu volumen está cerca del threshold. Reduce ritmo de envíos:
- Pausa workflows masivos.
- Espacia los outgoings (al menos 2-3 s entre mensajes a JIDs nuevos).
- Mira
alertsen el snapshot: si dicehigh_velocityes ritmo,burst_outreaches muchos JIDs nuevos en poco tiempo,low_deliveryes que WhatsApp ya está rechazando.
Cuando se aclare (5-10 min sin nuevos triggers), el level baja automáticamente.
Glosario¶
202 queued: respuesta del endpoint /webhook cuando la instancia
está disconnected. qrsgen encoló el mensaje en el outbox y lo entregará
al volver (TTL 5 min). NO es un error.
503 queue full: respuesta cuando el outbox de la instancia llegó a
MaxQueueDepth (200 default). Significa que la instancia lleva mucho
rato caída sin que nadie la rescate.
Error al enviar: típicamente lo que el panel del downstream muestra cuando un POST a qrsgen falló (TCP refused durante restart, HMAC mismatch, etc.). Cosmético si el mensaje sí se entregó.
Disconnected vs logged_out: disconnected = sesión cayó pero se
puede recuperar; logged_out = sesión invalidada server-side, hay que
re-parear.
Grace period: tiempo de espera silencioso tras un evento antes de
emitir su pill. 60s para unreachable, 5s para reconnected.
Ban-risk level: high: los thresholds (velocity/diversity/delivery) están cruzados sostenidamente. Riesgo inminente de strike.
Reducir ritmo: pausar workflows masivos, espaciar más los envíos (2-3s entre mensajes), evitar nuevos JIDs hasta que el level baje.
Cosmético (error): el sistema reporta error pero el mensaje sí se entregó correctamente. Frecuente con notas privadas que el downstream intenta dispatch erróneamente.