crowdsecurity/crowdsec · error
while building request: %w
Error message
while building request: %w
What it means
SignalService.Add builds the POST /signals request via PrepareRequest before sending alert signals to the API; if construction fails (trailing-slash BaseURL violation, URL parse error, JSON marshal failure of the AddSignalsRequest, gzip error), it wraps the error as 'while building request'. Nothing has been sent to the server yet — the failure is entirely client-side.
Source
Thrown at pkg/apiclient/signal.go:19
package apiclient
import (
"context"
"fmt"
"net/http"
"github.com/crowdsecurity/crowdsec/pkg/modelscapi"
log "github.com/sirupsen/logrus"
)
type SignalService service
func (s *SignalService) Add(ctx context.Context, signals *modelscapi.AddSignalsRequest) (interface{}, *Response, error) {
u := fmt.Sprintf("%s/signals", s.client.URLPrefix)
req, err := s.client.PrepareRequest(ctx, http.MethodPost, u, &signals)
if err != nil {
return nil, nil, fmt.Errorf("while building request: %w", err)
}
var response interface{}
resp, err := s.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("Signal push response : http %s", resp.Response.Status)
} else {
log.Debugf("Signal push response : http %s", resp.Response.Status)
}
return &response, resp, nil
}
View on GitHub (pinned to 909b515798)
Solutions
- Inspect the wrapped inner error for the concrete cause
- Verify BaseURL is absolute and its path ends with '/'
- Ensure the AddSignalsRequest payload contains only JSON-serializable values (no NaN/Inf floats, channels, or funcs)
- Validate the URLPrefix/version prefix configuration if the endpoint URL fails to parse
Example fix
// before
req, err := s.client.PrepareRequest(ctx, http.MethodPost, u, &signals)
if err != nil {
return nil, nil, fmt.Errorf("while building request: %w", err)
}
// after (pre-marshal validation)
if err := validateSignalsJSONMarshalable(signals); err != nil {
return nil, nil, fmt.Errorf("signals payload not serializable: %w", err)
}
req, err := s.client.PrepareRequest(ctx, http.MethodPost, u, &signals)
if err != nil {
return nil, nil, fmt.Errorf("while building request: %w", err)
} Defensive patterns
Strategy: validation
Validate before calling
// before calling SignalService.Add
if !strings.HasSuffix(client.BaseURL.Path, "/") {
return errors.New("client BaseURL must end with a trailing slash")
}
if _, err := json.Marshal(signals); err != nil {
return fmt.Errorf("signals payload not serializable: %w", err)
} Type guard
func canSendSignals(client *apiclient.ApiClient) bool {
return client != nil && strings.HasSuffix(client.BaseURL.Path, "/")
} Try / catch
_, _, err := client.Signal.Add(ctx, signals)
if err != nil {
if strings.Contains(err.Error(), "while building request") {
// construction-stage failure: validate URL and payload, no retry will help
return fmt.Errorf("invalid signal request: %w", err)
}
return err
} Prevention
- Sanitize alert data (no NaN/Inf floats) before building AddSignalsRequest
- Normalize BaseURL with a trailing slash when constructing the client
- Add a test that marshals a representative signals payload
- Verify URLPrefix/version configuration matches the server's API version
When it happens
Trigger: s.client.PrepareRequest(ctx, http.MethodPost, u, &signals) returns an error before any network I/O: BaseURL without trailing slash, invalid URL prefix, or a signals body containing values the JSON encoder cannot marshal (e.g. NaN in a float field, unsupported types).
Common situations: Custom tooling building an ApiClient with a hand-parsed URL missing the trailing slash; ingesting alert data containing non-JSON-serializable values; version prefix/URLPrefix misconfigured so BaseURL.Parse fails.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- while building request: %w
- context must be non-nil
- authenticate watcher (%s): %w
- BaseURL must have a trailing slash, but %q does not
- writing to gzip writer: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/4dfe35111ed51f01.
Report an issue: GitHub.