GET /v1/alerts?origin=X causes systematic timeout (25s+) while same query without origin= responds in 13ms
Los mantenedores suelen responder en 2 días
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 48/100
Línea de trabajo
Start by tracing the Go handler for GET /v1/alerts and how it applies the origin query parameter; compare that path with the working value and scope filters. Reproduce with the supplied curl request, then profile or instrument the handler to locate the delay rather than assume SQLite is responsible. Done means origin filtering returns promptly and the regression is covered by a test.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Description
Calling GET /v1/alerts?has_active_decision=true&origin=X against the local LAPI hangs and eventually times out (>25s, observed up to 20s+ on every call), while the same request without the origin= parameter completes in ~13ms with HTTP 200. This makes cscli decisions list --origin X unusable in scripts (and breaks any tooling that relies on it, e.g. cron jobs that filter decisions by origin).
The bottleneck is not SQLite — the underlying SQL query completes in <100ms with or without an index on decisions.origin. The hang is somewhere in the Go handler for the origin filter on this route.
Environment
- CrowdSec:
v1.7.8-debian-pragmatic-amd64-63227459(Codename:alphaga, BuildDate: 2026-05-11) - GoVersion: 1.26.2
- OS: Ubuntu 24.04.4 LTS, kernel 6.17.0-23-generic
- DB backend: SQLite (44 MB, ~44k rows in
decisions, ~33k active) - LAPI binding:
127.0.0.1:8080(local-only)
Steps to reproduce
# Get a JWT
LOGIN=$(grep "^login:" /etc/crowdsec/local_api_credentials.yaml | awk '{print $2}')
PASS=$(grep "^password:" /etc/crowdsec/local_api_credentials.yaml | awk '{print $2}')
JWT=$(curl -s -X POST http://127.0.0.1:8080/v1/watchers/login \
-H "Content-Type: application/json" \
-d "{\"machine_id\":\"$LOGIN\",\"password\":\"$PASS\"}" \
| jq -r .token)
# Fast — completes in ~13ms
time curl -s -m 25 -H "Authorization: Bearer $JWT" \
"http://127.0.0.1:8080/v1/alerts?has_active_decision=true&include_capi=false&limit=100" \
-o /dev/null -w "HTTP %{http_code} time=%{time_total}s\n"
# Hangs — times out (HTTP 000 after 25s)
time curl -s -m 25 -H "Authorization: Bearer $JWT" \
"http://127.0.0.1:8080/v1/alerts?has_active_decision=true&include_capi=false&limit=100&origin=cscli" \
-o /dev/null -w "HTTP %{http_code} time=%{time_total}s\n"
Observed output:
HTTP 200 time=0.013825s
HTTP 000 time=25.002199s
Same behaviour through cscli:
$ time cscli decisions list -o json | wc -c # ~0.3s, returns full payload
$ time cscli decisions list --origin cscli -o json # always 15s timeout (cscli's internal timeout)
$ time cscli decisions list --origin cscli # same timeout in table mode
$ time cscli decisions list --value 1.2.3.4 -o json # ~0.2s, works
$ time cscli decisions list --scope Ip -o json # ~0.2s, works
Only the origin filter is affected. Reproducible with any value of origin (cscli, crowdsec, lists, CAPI).
Investigation
To rule out the database as the bottleneck:
- Existing indexes on
decisions:decision_value,decision_until,decision_alert_decisions,decision_start_ip_end_ip. No index onorigin. - Direct SQLite benchmark of the equivalent JOIN (
alerts⨝decisionsfiltered byoriginanduntil > now()): 70ms (usesdecision_untilindex). - Created
CREATE INDEX idx_decision_origin_until ON decisions(origin, until)+ANALYZE→ SQL query drops to 21ms withEXPLAIN QUERY PLANconfirming use of the new index. cscli --originstill times out at 20s with the new index in place. Index dropped afterwards.
→ The handler is not SQL-bound. The hang happens elsewhere in the Go path for the origin= query parameter. Possible candidates: a misbehaving filter loop, an N+1 fetch, a deadlock, or unbounded pagination. The TCP connection from cscli/curl stays in ESTABLISHED state during the whole hang, then the client times out.
Expected behavior
GET /v1/alerts?origin=X should return in the same order of magnitude as the unfiltered query (10s–100s of ms), since filtering reduces the result set rather than expanding it.
Workaround
Drop the origin= filter and filter client-side:
# Fetch all active alerts (one call, ~300ms)
result = subprocess.run(
["cscli", "decisions", "list", "-o", "json"],
capture_output=True, text=True, timeout=15,
)
alerts = json.loads(result.stdout)
# Filter by origin in Python
cscli_bans = {
dec["value"]
for alert in alerts
for dec in (alert.get("decisions") or [])
if dec.get("origin") == "cscli"
and dec.get("type") == "ban"
and dec.get("scope", "").lower() == "ip"
}
This is a strict regression for callers that need the filter, but works around the issue completely.
Happy to provide additional diagnostics (pprof, strace, journalctl, full schema dump) if useful.
- Lenguaje dominante
- Go
- Estrellas
- 15.1k
- Forks
- 726
- Merge medio
- 2 d 51 min
- PR fusionados (30 d)
- 18
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de crowdsecurity/crowdsec
-
[docker] Align build and debian releasePosiblemente ocupada @albundy83 la tomó hace 2 días. Abiertokind/enhancement needs/triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
crowdsecurity/crowdsec#4803 · 3 comentarios ·
Los mantenedores suelen responder en 2 días
-
Bucket queues preallocate all their slots when the bucket is createdPosiblemente ocupada @AdzerKI la tomó hace 4 días. Abiertokind/bug needs/triage os/linux
Dificultad 2/5 1-3 horas Aptitud para principiantes 83/100
crowdsecurity/crowdsec#4799 · 3 comentarios ·
Los mantenedores suelen responder en 2 días
-
kind/bug needs/triage os/linux
Dificultad 3/5 1-2 días Aptitud para principiantes 25/100
crowdsecurity/crowdsec#4797 · 1 comentario ·
Los mantenedores suelen responder en 2 días
-
needs/kind needs/triage
Dificultad 5/5 Más de una semana Aptitud para principiantes 38/100
crowdsecurity/crowdsec#4795 · 2 comentarios ·
Los mantenedores suelen responder en 2 días
-
kind/bug needs/triage os/linux
Dificultad 4/5 3-5 días Aptitud para principiantes 45/100
crowdsecurity/crowdsec#4790 · 1 comentario ·
Los mantenedores suelen responder en 2 días
Todos los issues de crowdsecurity/crowdsec
Issues similares
-
type/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
area/admin/user area/internationalization automated-triage issue/auto-triaged type/bug
Dificultad 1/5 Menos de una hora Aptitud para principiantes 76/100
grafana/grafana#137281 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
go good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
mvanhorn/printing-press-library#2447 ·
Los mantenedores suelen responder en 1 día