crowdsecurity/crowdsec · error
while performing request: %w
Error message
while performing request: %w
What it means
DecisionDeleteService.Add wraps any failure of client.Do — the actual HTTP round trip for POST /decisions/delete. This covers transport errors (connection refused, DNS, timeout, TLS) as well as response-decoding errors; the returned resp (when non-nil) holds the server's status for further inspection. The method separately logs non-200 statuses after this, so this wrapper is the network/decoding failure path.
Source
Thrown at pkg/apiclient/decisions_sync_service.go:28
"github.com/crowdsecurity/crowdsec/pkg/models"
)
type DecisionDeleteService service
// DecisionDeleteService purposely reuses AddSignalsRequestItemDecisions model
func (d *DecisionDeleteService) Add(ctx context.Context, deletedDecisions *models.DecisionsDeleteRequest) (interface{}, *Response, error) {
u := fmt.Sprintf("%s/decisions/delete", d.client.URLPrefix)
req, err := d.client.PrepareRequest(ctx, http.MethodPost, u, &deletedDecisions)
if err != nil {
return nil, nil, fmt.Errorf("while building request: %w", err)
}
var response interface{}
resp, err := d.client.Do(ctx, req, &response)
if err != nil {
return nil, resp, fmt.Errorf("while performing request: %w", err)
}
if resp.Response.StatusCode != http.StatusOK {
log.Warnf("Decisions delete response: http %s", resp.Response.Status)
} else {
log.Debugf("Decisions delete response: http %s", resp.Response.Status)
}
return &response, resp, nil
}
View on GitHub (pinned to 909b515798)
Solutions
- Check LAPI availability and logs at the time of the delete
- Inspect the returned *Response for a status code to distinguish HTTP-level vs transport-level failure
- Increase the context deadline / add retry with backoff for transient network errors
- Verify TLS/CA configuration between client and LAPI
Example fix
// before
resp, err := d.client.Do(ctx, req, &response)
if err != nil {
return nil, resp, fmt.Errorf("while performing request: %w", err)
}
// after (caller-side retry on transient errors)
var lastErr error
for i := 0; i < 3; i++ {
resp, err := d.client.Do(ctx, req, &response)
if err == nil {
break
}
lastErr = fmt.Errorf("while performing request: %w", err)
time.Sleep(time.Duration(1<<i) * time.Second)
}
if lastErr != nil {
return nil, nil, lastErr
} Defensive patterns
Strategy: retry
Validate before calling
// pre-check LAPI reachability before deleting decisions
resp, err := http.Get(client.BaseURL.String() + "health")
if err != nil {
return fmt.Errorf("LAPI unreachable, skipping decisions delete: %w", err)
}
resp.Body.Close() Type guard
func isTransient(err error) bool {
return errors.Is(err, context.DeadlineExceeded) ||
errors.Is(err, syscall.ECONNRESET) ||
errors.Is(err, syscall.ECONNREFUSED) ||
errors.Is(err, io.ErrUnexpectedEOF)
} Try / catch
_, resp, err := client.DecisionsDelete.Add(ctx, req)
if err != nil {
if isTransient(err) {
return retryWithBackoff(ctx, 3, func() error { _, _, err := client.DecisionsDelete.Add(ctx, req); return err })
}
if resp != nil && resp.Response != nil {
return fmt.Errorf("decisions delete got http %s", resp.Response.Status)
}
return err
} Prevention
- Set generous context deadlines for LAPI calls under load
- Retry transient network errors with exponential backoff
- Monitor LAPI availability and alert on restarts
- Handle context cancellation explicitly in long-running bouncers
When it happens
Trigger: d.client.Do(ctx, req, &response) returns an error: LAPI unreachable, connection reset, context canceled/deadline exceeded, or the response body could not be decoded into the response model.
Common situations: LAPI down or restarted while a bouncer deletes decisions; network interruption; request timeout under load; TLS certificate problems; context canceled because the caller's deadline expired mid-call.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- api register (%s): %w
- unexpected status code: %d
- appsec datasource requires a hub. this is a bug, please repo
- appsec datasource requires a lapi client configuration. this
- missing lapi client credentials
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/9945fca12cdcea3f.
Report an issue: GitHub.