crowdsecurity/crowdsec · error
APIKey is empty
Error message
APIKey is empty
What it means
APIKeyTransport is an http.RoundTripper that injects an API key into outgoing requests. RoundTrip refuses to execute if the transport's APIKey field is empty, because a request sent without a key would fail authentication downstream anyway.
Source
Thrown at pkg/apiclient/auth_key.go:22
"errors"
"net/http"
"net/http/httputil"
log "github.com/sirupsen/logrus"
)
type APIKeyTransport struct {
APIKey string
// Transport is the underlying HTTP transport to use when making requests.
// It will default to http.DefaultTransport if nil.
Transport http.RoundTripper
UserAgent string
}
// RoundTrip implements the RoundTripper interface.
func (t *APIKeyTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if t.APIKey == "" {
return nil, errors.New("APIKey is empty")
}
// We must make a copy of the Request so
// that we don't modify the Request we were given. This is required by the
// specification of http.RoundTripper.
req = cloneRequest(req)
req.Header.Add("X-Api-Key", t.APIKey)
if t.UserAgent != "" {
req.Header.Add("User-Agent", t.UserAgent)
}
log.Debugf("req-api: %s %s", req.Method, req.URL.String())
if log.IsLevelEnabled(log.TraceLevel) {
dump, _ := httputil.DumpRequest(req, true)
log.Tracef("auth-api request: %s", string(dump))
}View on GitHub (pinned to 909b515798)
Solutions
- Set the APIKey field on the APIKeyTransport before using the client
- Load the key from config/env (e.g. LocalAPIider credentials) and validate it is non-empty at startup
- Regenerate credentials with cscli (e.g. 'cscli bouncers add') and put the key in the client config
Example fix
// before
tr := &apiclient.APIKeyTransport{Transport: base}
client := &http.Client{Transport: tr}
// after
if apiKey == "" {
return nil, fmt.Errorf("missing API key")
}
tr := &apiclient.APIKeyTransport{APIKey: apiKey, Transport: base}
client := &http.Client{Transport: tr} Defensive patterns
Strategy: validation
Validate before calling
// Go: check the key before constructing the transport
if apiKey == "" {
return nil, fmt.Errorf("no API key configured for LAPI client")
}
tr := &apiclient.APIKeyTransport{APIKey: apiKey, Transport: http.DefaultTransport} Try / catch
resp, err := client.Do(req)
if err != nil && strings.Contains(err.Error(), "APIKey is empty") {
return fmt.Errorf("client misconfigured: %w", err)
} Prevention
- Fail fast at startup if the configured API key is empty
- Load keys from config files/env and log (without printing) their presence
- Rotate and distribute keys via cscli rather than hardcoding
When it happens
Trigger: Constructing an APIKeyTransport (or an apiclient built on one) with an empty APIKey string and then issuing any HTTP request through it.
Common situations: Config file missing api_key / LAPI key; environment variable not set when building the client; reading the key from a file that is empty or failed to load; registering a bouncer without supplying its key.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/ca4329f39a68ec84.
Report an issue: GitHub.