crowdsecurity/crowdsec · warning

invalid headers

Error message

invalid headers

What it means

When the HTTP source is configured with auth_type: headers, authorizeRequest() (pkg/acquisition/modules/http/run.go:42) requires every configured header key/value pair to be present and equal on the incoming request. Any single mismatched or missing header causes rejection with 'invalid headers'.

Source

Thrown at pkg/acquisition/modules/http/run.go:42

	"github.com/crowdsecurity/crowdsec/pkg/pipeline"
)

func authorizeRequest(r *http.Request, hc *Configuration) error {
	if hc.AuthType == "basic_auth" {
		username, password, ok := r.BasicAuth()
		if !ok {
			return errors.New("missing basic auth")
		}

		if username != hc.BasicAuth.Username || password != hc.BasicAuth.Password {
			return errors.New("invalid basic auth")
		}
	}

	if hc.AuthType == "headers" {
		for key, value := range hc.Headers {
			if r.Header.Get(key) != value {
				return errors.New("invalid headers")
			}
		}
	}

	return nil
}

func rejectBody(w http.ResponseWriter, err error) error {
	if maxBytesErr, ok := errors.AsType[*http.MaxBytesError](err); ok {
		w.WriteHeader(http.StatusRequestEntityTooLarge)
		return fmt.Errorf("body size exceeds max body size: %d", maxBytesErr.Limit)
	}

	w.WriteHeader(http.StatusBadRequest)

	return fmt.Errorf("failed to read body: %w", err)
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Send all headers exactly as configured under auth_type.headers in the source config, e.g. curl -H 'X-API-Key: value'.
  2. Compare header names and values character-by-character (values are compared with !=, so exact match required).
  3. Check intermediate proxies/load balancers are not stripping or renaming the custom headers.
  4. Remove unused entries from the auth_type.headers map in the config to reduce required headers.

Example fix

// before
curl -H 'X-API-Key: wrong' http://localhost:8080/logs

// after
curl -H 'X-API-Key: expected-value' http://localhost:8080/logs
Defensive patterns

Strategy: validation

Validate before calling

for k, v := range cfg.AuthTypeHeaders {
    if r.Header.Get(k) != v {
        // missing or mismatched header; fix client headers before sending
    }
}

Type guard

func hasRequiredHeaders(r *http.Request, want map[string]string) bool {
    for k, v := range want {
        if r.Header.Get(k) != v { return false }
    }
    return true
}

Try / catch

if err := authorizeRequest(req, cfg); err != nil {
    if err.Error() == "invalid headers" {
        // diff sent headers against auth_type.headers config
    }
}

Prevention

When it happens

Trigger: Sending a request to an http source with auth_type: headers that omits one of the configured headers or sends a different value (including case/whitespace differences for the value).

Common situations: Client sends fewer headers than configured; header value differs by case or whitespace; reverse proxy renames or drops custom headers (e.g. X- prefix handling); config updated with a new required header that old clients don't send.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/e43e6a49edab568b. Report an issue: GitHub.