{"record":{"id":"0a90d14dc4e000bd","repo":"crowdsecurity/crowdsec","slug":"get-scenario-in-db-w","errorCode":null,"errorMessage":"get scenario in db: %w","messagePattern":"get scenario in db: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/apic.go","lineNumber":270,"sourceCode":"//\n// If a new token is obtained, it is saved back to the database for caching.\nfunc (a *apic) Authenticate(ctx context.Context, config *csconfig.OnlineApiClientCfg) error {\n\ttransport := a.apiClient.GetClient().Transport.(*apiclient.JWTTransport)\n\n\ttoken, err := a.dbClient.LoadAPICToken(ctx, log.StandardLogger())\n\tif err == nil {\n\t\tlog.Debug(\"using valid token from DB\")\n\t\ttransport.Token = token.Raw\n\t\ttransport.Expiration = token.ExpiresAt\n\n\t\treturn nil\n\t}\n\n\tlog.WithError(err).Debug(\"No useful token, authenticating\")\n\n\tscenarios, err := a.FetchScenariosListFromDB(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"get scenario in db: %w\", err)\n\t}\n\n\tpassword := strfmt.Password(config.Credentials.Password)\n\n\tauthResp, _, err := a.apiClient.Auth.AuthenticateWatcher(ctx, models.WatcherAuthRequest{\n\t\tMachineID: &config.Credentials.Login,\n\t\tPassword:  &password,\n\t\tScenarios: scenarios,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"authenticate watcher (%s): %w\", config.Credentials.Login, err)\n\t}\n\n\tif err = transport.Expiration.UnmarshalText([]byte(authResp.Expire)); err != nil {\n\t\treturn fmt.Errorf(\"unable to parse jwt expiration: %w\", err)\n\t}\n\n\ttransport.Token = authResp.Token","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/apic.go#L252-L288","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// before authenticating, sanity-check DB access\nif _, err := dbClient.ListMachines(ctx); err != nil {\n\treturn fmt.Errorf(\"local DB not readable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"scenarios, err := a.FetchScenariosListFromDB(ctx)\nif err != nil {\n\treturn fmt.Errorf(\"get scenario in db: %w\", err)\n}\n// caller: inspect with errors.As for sql/sqlite errors and decide whether to retry or fail startup","preventionTips":["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"],"tags":["database","authentication","crowdsec","startup"],"backgroundTag":"database-query-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}