crowdsecurity/crowdsec · error
unable to query PAPI : %s (%d)
Error message
unable to query PAPI : %s (%d)
What it means
GetPermissions queries the local PAPI (Pull API) service to check permissions. When PAPI returns a non-success HTTP status, the error response body is decoded and surfaced as 'unable to query PAPI : <message> (<status code>)'. It means the PAPI service itself responded but rejected or failed the request.
Source
Thrown at pkg/apiserver/papi.go:187
return PapiPermCheckSuccess{}, fmt.Errorf("failed to create request: %w", err)
}
resp, err := httpClient.Do(req)
if err != nil {
return PapiPermCheckSuccess{}, fmt.Errorf("failed to get response: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
errResp := PapiPermCheckError{}
err = json.NewDecoder(resp.Body).Decode(&errResp)
if err != nil {
return PapiPermCheckSuccess{}, fmt.Errorf("failed to decode response: %w", err)
}
return PapiPermCheckSuccess{}, fmt.Errorf("unable to query PAPI : %s (%d)", errResp.Error, resp.StatusCode)
}
respBody := PapiPermCheckSuccess{}
err = json.NewDecoder(resp.Body).Decode(&respBody)
if err != nil {
return PapiPermCheckSuccess{}, fmt.Errorf("failed to decode response: %w", err)
}
return respBody, nil
}
func reverse(s []longpollclient.Event) []longpollclient.Event {
a := make([]longpollclient.Event, len(s))
copy(a, s)
for i := len(a)/2 - 1; i >= 0; i-- {
opp := len(a) - 1 - iView on GitHub (pinned to 909b515798)
Solutions
- Check the PAPI URL and credentials in the LAPI configuration (api.server.pull_api configuration section)
- Verify the PAPI service is enabled in the crowdsec API server config
- Inspect the embedded status code and PAPI error message in the log to identify the server-side cause
- Check network/proxy between crowdsec and the PAPI endpoint
Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := client.Get(papiURL); if err != nil || resp.StatusCode >= 300 { /* handle before decode */ } Try / catch
if _, err := GetPermissions(ctx); err != nil { if strings.Contains(err.Error(), "unable to query PAPI") { log.Printf("PAPI returned error: %v", err); /* fallback or retry */ } } Prevention
- Keep PAPI credentials and URL in config validated at startup
- Monitor PAPI endpoint health before scheduled pulls
- Pin compatible crowdsec versions across components
When it happens
Trigger: The HTTP response from the PAPI server has a non-2xx status code; the body is successfully decoded into the error struct and its Error field plus status code are wrapped into this message.
Common situations: PAPI service misconfigured (wrong URL/port in lapi configuration), expired or invalid machine credentials, PAPI endpoint disabled in the API server config, or the service is unhealthy behind a proxy returning 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- failed to decode response: %w
- unauthorized
- request quota exceeded, please reduce your request rate
- ip not found
- errUnauthorized
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/0d2893310d625bf2.
Report an issue: GitHub.