zitadel/zitadel · critical
cannot start DB client for queries: %w
Error message
cannot start DB client for queries: %w
What it means
startZitadel calls database.Connect to create the primary PGx pool for queries. If the connection to the configured PostgreSQL database cannot be established, the error is wrapped as 'cannot start DB client for queries'. ZITADEL cannot serve any traffic without this client, so startup aborts.
Source
Thrown at cmd/start/start.go:184
Keys *encryption.EncryptionKeys
Eventstore *eventstore.Eventstore
Queries *query.Queries
AuthzRepo authz_repo.Repository
Storage static.Storage
Commands *command.Commands
Router *mux.Router
TLSConfig *tls.Config
Shutdown chan<- os.Signal
}
func startZitadel(ctx context.Context, config *Config, masterKey string, server chan<- *Server) error {
showBasicInformation(config)
i18n.MustLoadSupportedLanguagesFromDir()
dbClient, err := database.Connect(config.Database, false)
if err != nil {
return fmt.Errorf("cannot start DB client for queries: %w", err)
}
new_domain.SetPool(v3_postgres.PGxPool(dbClient.Pool))
keyStorage, err := cryptoDB.NewKeyStorage(dbClient, masterKey)
if err != nil {
return fmt.Errorf("cannot start key storage: %w", err)
}
keys, err := encryption.EnsureEncryptionKeys(ctx, config.EncryptionKeys, keyStorage)
if err != nil {
return err
}
q, err := queue.NewQueue(&queue.Config{
Client: dbClient,
})
if err != nil {
return err
}
View on GitHub (pinned to 13948f2bcd)
Solutions
- Verify the wrapped error and test connectivity with psql using the exact connection parameters from your config
- Confirm Postgres is running and reachable (docker compose ps / kubectl get pods) and wait for readiness
- Check host, port, user, password, database, ssl_mode in config or ZITADEL_DATABASE_POSTGRES_* environment variables
- If Postgres starts slower than ZITADEL, add readiness gating/retries (e.g. depends_on: condition: service_healthy)
Example fix
// before
database:
postgres:
host: db
port: 5433
// after
database:
postgres:
host: db
port: 5432 Defensive patterns
Strategy: retry
Validate before calling
// before starting, probe the DB
nc, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), 3*time.Second)
if err != nil { return fmt.Errorf("postgres unreachable: %w", err) }
nc.Close() Try / catch
if err := waitForPostgres(cfg, 30*time.Second); err != nil {
log.Fatalf("DB not reachable in time: %v", err)
} Prevention
- Use healthcheck-gated orchestration (depends_on: service_healthy)
- Keep a single source of truth for DB credentials (env/secret manager)
- Test connectivity with psql from inside the container before startup
When it happens
Trigger: database.Connect(config.Database, false) fails: wrong host/port/user/password/database in config, TLS misconfiguration, DNS failure, or the Postgres server is unreachable.
Common situations: Postgres not yet ready in docker-compose/K8s (startup race), wrong ZITADEL_DATABASE_POSTGRES_* env vars, firewall/network policy blocking 5432, bad SSL mode or expired certificates.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- unable to get current database: %w
- unable to get current user: %w
- unable to get current user: %w
- MaxOpenConns of the database must be higher than 3 or 0 for
- MaxIdleConns of the database must be higher than 3 or 0 for
AI-assisted analysis of zitadel/zitadel@13948f2bcd (2026-09-06).
Data as JSON: /api/errors/62a1012230cfef9d.
Report an issue: GitHub.