zitadel/zitadel · critical
unable to create projections: %w
Error message
unable to create projections: %w
What it means
In Setup (cmd/setup/setup.go), projection.Create initializes the projection tables and their handlers in the database. When that fails, ZITADEL wraps the error with "unable to create projections". This means the database could not create the projection schemas/tables or start the projection handlers, so no migration steps run afterwards.
Source
Thrown at cmd/setup/setup.go:264
steps.s61IDPTemplate6SAMLSignatureAlgorithm = &IDPTemplate6SAMLSignatureAlgorithm{dbClient: dbClient}
steps.s62HTTPProviderAddSigningKey = &HTTPProviderAddSigningKey{dbClient: dbClient}
steps.s63AlterResourceCounts = &AlterResourceCounts{dbClient: dbClient}
steps.s64ChangePushPosition = &ChangePushPosition{dbClient: dbClient}
steps.s65FixUserMetadata5Index = &FixUserMetadata5Index{dbClient: dbClient}
steps.s66SessionRecoveryCodeCheckedAt = &SessionRecoveryCodeCheckedAt{dbClient: dbClient}
steps.s67SyncMemberRoleFields = &SyncMemberRoleFields{dbClient: dbClient}
steps.s68TargetAddPayloadTypeColumn = &TargetAddPayloadTypeColumn{dbClient: dbClient}
steps.s69CacheTablesLogged = &CacheTablesLogged{dbClient: dbClient}
steps.s70AddEventStoreCommandEnforceOwner = &AddEventStoreCommandEnforceOwnerColumn{dbClient: dbClient}
steps.s71JWTProvideAddAudienceColumn = &JWTProvideAddAudienceColumn{dbClient: dbClient}
steps.s72AddColumnsToLoginNamesView = &AddColumnsToLoginNamesView{dbClient: dbClient}
steps.s73FixUserGrantRoles = &FixUserGrantRoles{eventstore: eventstoreClient}
steps.s74Apps7OIDCConfigsAddRegistrationToken = &Apps7OIDCConfigsAddRegistrationToken{dbClient: dbClient}
steps.s75Apps7OIDCConfigsAddAppLinkConfig = &Apps7OIDCConfigsAddAppLinkConfig{dbClient: dbClient}
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
if err != nil {
return fmt.Errorf("unable to create projections: %w", err)
}
for _, step := range []migration.Migration{
steps.s14NewEventsTable,
steps.s40InitPushFunc,
steps.s1ProjectionTable,
steps.s2AssetsTable,
steps.s28AddFieldTable,
steps.s31AddAggregateIndexToFields,
steps.s46InitPermissionFunctions,
steps.FirstInstance,
steps.s5LastFailed,
steps.s6OwnerRemoveColumns,
steps.s7LogstoreTables,
steps.s8AuthTokens,
steps.s12AddOTPColumns,
steps.s13FixQuotaProjection,
steps.s15CurrentStates,View on GitHub (pinned to 13948f2bcd)
Solutions
- Inspect the wrapped error (%w): if it's connection refused/auth failed, fix the database DSN and credentials in your config.
- Grant the configured database user CREATE privileges on the target schema/database.
- Verify the database is reachable from where setup runs (psql with the same DSN).
- If a previous setup failed midway, clean up partially created projection tables or restore a clean schema, then re-run setup.
Example fix
// before (config.yaml) — wrong port
Database:
postgres:
Host: db
Port: 5433
// after
Database:
postgres:
Host: db
Port: 5432 Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight DB check before running setup:
cmd := exec.Command("psql", dsn, "-c", "SELECT 1")
if err := cmd.Run(); err != nil {
return fmt.Errorf("database not reachable/authorized: %w", err)
} Try / catch
err := projection.Create(ctx, dbClient, esClient, config.Projections, nil, nil, nil)
if err != nil {
// retry transient network failures with backoff; surface otherwise
return fmt.Errorf("unable to create projections: %w", err)
} Prevention
- Verify DB credentials and network reachability before every setup run.
- Grant the DB user CREATE privileges on the target schema.
- Ensure prior failed setups are cleaned up so projection tables don't half-exist.
- In K8s, add init containers or readiness checks so setup waits for Postgres.
When it happens
Trigger: projection.Create returns an error during `zitadel setup`: the database is unreachable, the user lacks CREATE privileges, a projection table already exists in an incompatible state, or an internal projection handler query fails.
Common situations: Wrong database host/port/credentials in config (connection refused or auth failure); Postgres user without DDL rights on the schema; partially-failed previous setup leaving half-created projection tables; network/firewall blocking the DB during a Kubernetes setup job.
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
- %s: VacuumThreshold and AnalyzeThreshold must be greater tha
- MaxOpenConns of the database must be higher than 3 or 0 for
- cannot start key storage: %w
- %s %s: %w
- %s %s: %w
AI-assisted analysis of zitadel/zitadel@13948f2bcd (2026-09-06).
Data as JSON: /api/errors/fd96c83aaa7ddcfe.
Report an issue: GitHub.