crowdsecurity/crowdsec · error
get scenario in db: %w
Error message
get scenario in db: %w
What it means
Authenticate, called by NewAPIC during startup, refreshes the watcher token when none is usable. Before calling CAPI it fetches the machine list to aggregate scenarios; a failure there is wrapped as 'get scenario in db'. This is a startup-blocking error: the watcher cannot authenticate to CAPI.
Source
Thrown at pkg/apiserver/apic.go:270
//
// If a new token is obtained, it is saved back to the database for caching.
func (a *apic) Authenticate(ctx context.Context, config *csconfig.OnlineApiClientCfg) error {
transport := a.apiClient.GetClient().Transport.(*apiclient.JWTTransport)
token, err := a.dbClient.LoadAPICToken(ctx, log.StandardLogger())
if err == nil {
log.Debug("using valid token from DB")
transport.Token = token.Raw
transport.Expiration = token.ExpiresAt
return nil
}
log.WithError(err).Debug("No useful token, authenticating")
scenarios, err := a.FetchScenariosListFromDB(ctx)
if err != nil {
return fmt.Errorf("get scenario in db: %w", err)
}
password := strfmt.Password(config.Credentials.Password)
authResp, _, err := a.apiClient.Auth.AuthenticateWatcher(ctx, models.WatcherAuthRequest{
MachineID: &config.Credentials.Login,
Password: &password,
Scenarios: scenarios,
})
if err != nil {
return fmt.Errorf("authenticate watcher (%s): %w", config.Credentials.Login, err)
}
if err = transport.Expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {
return fmt.Errorf("unable to parse jwt expiration: %w", err)
}
transport.Token = authResp.TokenView on GitHub (pinned to 909b515798)
Solutions
- Verify the local DB works: run cscli machines list (same ListMachines path)
- Check DB config and backend availability; restore connectivity or fix credentials
- Ensure schema migrations ran (restart crowdsec / cscli db migrate equivalent)
- Restore crowdsec.db from backup or re-register the watcher (cscli machines add / capi register) if unrecoverable
Defensive patterns
Strategy: try-catch
Validate before calling
// before authenticating, sanity-check DB access
if _, err := dbClient.ListMachines(ctx); err != nil {
return fmt.Errorf("local DB not readable: %w", err)
} Try / catch
scenarios, err := a.FetchScenariosListFromDB(ctx)
if err != nil {
return fmt.Errorf("get scenario in db: %w", err)
}
// caller: inspect with errors.As for sql/sqlite errors and decide whether to retry or fail startup Prevention
- Verify crowdsec.db exists and is readable before startup (ls -l /var/lib/crowdsec/data/)
- Apply schema migrations when upgrading before re-enabling sharing
- Keep the DB backend (if remote) monitored for availability
When it happens
Trigger: a.FetchScenariosListFromDB(ctx) returns an error during the authenticate flow — i.e. the underlying ListMachines DB call fails (unreachable backend, missing/corrupt machines table, migration pending).
Common situations: crowdsec.db deleted or corrupted on a machine with existing CAPI enrollment; DB backend (Postgres/MySQL) down or credentials rotated; upgrade without schema migration; read-only mount under /var/lib/crowdsec/data.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- no configuration paths provided
- no database configuration provided
- unable to update
- unable to delete
- object not found
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/0a90d14dc4e000bd.
Report an issue: GitHub.