crowdsecurity/crowdsec · critical
unable to init database client: %w
Error message
unable to init database client: %w
What it means
NewServer fails when database.NewClient cannot open/initialize the configured DB backend (sqlite/mysql/postgres). The underlying driver error is wrapped, so the root cause is in the %w chain. It is thrown at startup of the local API server, before any HTTP handler exists.
Source
Thrown at pkg/apiserver/apiserver.go:127
// CustomRecoveryWithWriter returns a middleware for a writer that recovers from any panics and writes a 500 if there was one.
func CustomRecoveryWithWriter(c *gin.Context) {
defer recoverFromPanic(c)
c.Next()
}
// NewServer creates a LAPI server.
// It sets up a gin router, a database client, and a controller.
func NewServer(ctx context.Context, config *csconfig.LocalApiServerCfg, accessLogger *log.Entry) (*APIServer, error) {
var flushScheduler gocron.Scheduler
if accessLogger == nil {
accessLogger = log.StandardLogger().WithFields(nil)
}
dbClient, err := database.NewClient(ctx, config.DbConfig, config.DbConfig.NewLogger())
if err != nil {
return nil, fmt.Errorf("unable to init database client: %w", err)
}
if config.DbConfig.Flush != nil {
flushScheduler, err = dbClient.StartFlushScheduler(ctx, config.DbConfig.Flush)
if err != nil {
return nil, err
}
}
if !log.IsLevelEnabled(log.DebugLevel) {
gin.SetMode(gin.ReleaseMode)
}
router := gin.New()
router.ForwardedByClientIP = false
// set the remore address of the request to 127.0.0.1 if it comes from a unix socketView on GitHub (pinned to 909b515798)
Solutions
- Run `cscli lapi status` or check crowdsec logs for the wrapped root cause (e.g. dial tcp refused, permission denied).
- Verify db_config (type, host, port, user, password, db_path) in config.yaml.
- For MySQL/Postgres, test connectivity with mysql/psql using the same credentials.
- For SQLite, check the db_path directory exists and is writable by the crowdsec user.
- If the DB is corrupted, restore from backup or remove and let crowdsec re-create (`cscli machines` setup will be needed again).
Example fix
// before (config.yaml) db_config: type: sqlite3 db_path: /nonexistent/crowdsec.db // after db_config: type: sqlite3 db_path: /var/lib/crowdsec/data/crowdsec.db
Defensive patterns
Strategy: validation
Validate before calling
// before calling NewServer
if cfg.DbConfig == nil || (cfg.DbConfig.Type == "sqlite3" && cfg.DbConfig.DbPath == "") {
return fmt.Errorf("db_config is incomplete")
}
if err := pingDatabase(cfg.DbConfig); err != nil {
return fmt.Errorf("database unreachable: %w", err)
} Try / catch
srv, err := NewServer(ctx, cfg, nil)
if err != nil {
if strings.Contains(err.Error(), "unable to init database client") {
log.Fatalf("DB config/connect problem: %v", err)
}
return err
} Prevention
- Test DB credentials with the native client before starting LAPI.
- Use a managed/portable sqlite path with correct ownership.
- Validate config with `cscli config show` / dry-run on deploys.
- Monitor DB reachability in orchestration health checks.
When it happens
Trigger: Calling NewServer (via initAPIServer/cscli start) with a DbConfig whose DSN/credentials are wrong, the sqlite file path is unwritable, the DB server is down, or migrations fail.
Common situations: Bad db_config in /etc/crowdsec/local_api_credentials.yaml or config.yaml; MySQL/Postgres host unreachable or password changed; SQLite data dir permissions; corrupted SQLite file.
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
- get scenario in db: %w
- failed to generate DB connection string: %w
- missing lapi client credentials
- no appsec_config provided
- missing TLS key file
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/2b94abbee342f3eb.
Report an issue: GitHub.