crowdsecurity/crowdsec · error
authenticate watcher (%s): %w
Error message
authenticate watcher (%s): %w
What it means
InitLAPIClient authenticates the watcher against the LAPI with machine ID and password to obtain a JWT. When the AuthenticateWatcher call fails (any HTTP error response or transport failure), the error is wrapped with the login name so the developer knows which watcher failed. It is a client-side wrapper around a failed watcher login exchange.
Source
Thrown at pkg/apiclient/client.go:129
client := NewClient(&Config{
MachineID: login,
Password: pwd,
URL: apiURL,
PapiURL: papiURL,
VersionPrefix: "v1",
UpdateScenario: func(_ context.Context) ([]string, error) {
return scenarios, nil
},
})
authResp, _, err := client.Auth.AuthenticateWatcher(ctx, models.WatcherAuthRequest{
MachineID: &login,
Password: &pwd,
Scenarios: scenarios,
})
if err != nil {
return fmt.Errorf("authenticate watcher (%s): %w", login, err)
}
var expiration time.Time
if err := expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {
return fmt.Errorf("unable to parse jwt expiration: %w", err)
}
client.GetClient().Transport.(*JWTTransport).Token = authResp.Token
client.GetClient().Transport.(*JWTTransport).Expiration = expiration
lapiClient = client
return nil
}
func GetLAPIClient() (*ApiClient, error) {
if lapiClient == nil {
return nil, errors.New("client not initialized")View on GitHub (pinned to 909b515798)
Solutions
- Verify the machine is registered on the LAPI host: run 'cscli machines list' there; if missing, re-register with 'cscli lapi register' or delete/recreate the credentials
- Check api_url / lapi credentials in config for typos, wrong port, or stale password
- Test connectivity: curl the LAPI /health endpoint from the client host; fix network/firewall/TLS issues
- Inspect the inner wrapped error for the actual HTTP status or transport cause (e.g. 401 = bad password, connection refused = LAPI down)
Example fix
// before
if err != nil {
return fmt.Errorf("authenticate watcher (%s): %w", login, err)
}
// after (caller-side guard: check credentials before InitLAPIClient)
if login == "" || password == "" {
return errors.New("empty lapi login or password in configuration")
}
if err != nil {
return fmt.Errorf("authenticate watcher (%s): %w", login, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify credentials and LAPI reachability before InitLAPIClient
if login == "" || password == "" {
return errors.New("missing lapi credentials")
}
resp, err := http.Get(apiUrl + "/health")
if err != nil || resp.StatusCode != 200 {
return fmt.Errorf("LAPI not reachable at %s", apiUrl)
} Type guard
func isAuthFailure(err error) bool {
var apiErr *apiclient.APIError
if errors.As(err, &apiErr) {
return apiErr.StatusCode == http.StatusUnauthorized || apiErr.StatusCode == http.StatusForbidden
}
return false
} Try / catch
if err := apiclient.InitLAPIClient(ctx, apiUrl, papiUrl, login, pwd, scenarios); err != nil {
var apiErr *apiclient.APIError
if errors.As(err, &apiErr) && apiErr.StatusCode == 401 {
// re-register machine or refresh credentials
}
return fmt.Errorf("LAPI auth failed: %w", err)
} Prevention
- Keep lapi credentials in sync with 'cscli machines list' on the LAPI host
- Run 'cscli lapi register' rather than hand-editing credentials
- Monitor LAPI uptime; alert on machine deletions on the server
- Test connectivity and TLS to the LAPI before starting the watcher
When it happens
Trigger: client.Auth.AuthenticateWatcher(ctx, models.WatcherAuthRequest{...}) returns a non-nil error: the machine does not exist on LAPI, the password is wrong, the LAPI is unreachable, TLS verification fails, or the server returns 4xx/5xx.
Common situations: Machine was deleted from LAPI ('cscli machines delete' or DB reset) while crowdsec config still references it; wrong api_url or api_key in config.yaml; password mismatch after manual registration; LAPI not running or wrong port; certificate/TLS misconfig.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- invalid token for auto registration
- IP not in allowed range for auto registration
- bouncer not found
- failed to extract claims
- tls authentication required
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/04313cca2de63f58.
Report an issue: GitHub.