JuliusBrussee/caveman · error
postgres: inspect runtime identity
Error message
postgres: inspect runtime identity: %w
What it means
ValidateRuntimeIdentity runs a query against pg_roles (and pg_class ownership) to inspect the session's actual identity and privileges. If that inspection query itself fails — connection issue, missing privileges to read pg_roles, syntax/permission error — the underlying error is wrapped with this message.
Solutions
- Inspect the wrapped %w error for the root cause (connection refused, permission denied, etc.) and fix that first.
- Ensure ValidateRuntimeIdentity is called with a non-empty expected role name.
- Verify the role can read pg_roles/pg_get_userbyid output (default for any connected role) and that you connected to the intended database.
- Check pool health/credentials and retry if it was a transient connection error.
Example fix
// before err := postgresconfig.ValidateRuntimeIdentity(ctx, pool, "") // after err := postgresconfig.ValidateRuntimeIdentity(ctx, pool, "app_tenant_role")
Defensive patterns
Strategy: try-catch
Validate before calling
var exists bool err := pool.QueryRow(ctx, "SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname=$1)", role).Scan(&exists)
Try / catch
if err := postgresconfig.ValidateRuntimeIdentity(ctx, pool, role); err != nil {
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
log.Printf("identity inspection pg error %s: %s", pgErr.Code, pgErr.Message)
}
return fmt.Errorf("runtime identity: %w", err)
} Prevention
- Pass a verified, non-empty expected role name.
- Gate pool startup on database readiness checks.
- Retry transient pgconn errors before failing startup.
When it happens
Trigger: NewRuntimePool calls ValidateRuntimeIdentity with an expected role; the single-row inspection query errors, e.g. the expected role is empty (query parameter issue), the connection dropped, or pg_roles is unreadable from the current database.
Common situations: Connecting to a database where the app role lacks access to system catalogs; network interruption mid-startup; calling with expectedRole="" so the role-membership subquery cannot resolve.
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
- postgres: runtime current_user
- postgres: begin tenant schema inspection
- postgres: inspect tenant foreign keys
- postgres: inspect tenant tables
- postgres: parse DATABASE_URL
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/5929b4a554a180fb.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/postgresconfig/postgresconfig.go:166
r.rolbypassrls,
pg_has_role(current_user, $1, 'MEMBER'),
EXISTS (
SELECT 1
FROM pg_class c
JOIN pg_namespace n ON n.oid=c.relnamespace
JOIN information_schema.columns col
ON col.table_schema=n.nspname
AND col.table_name=c.relname
AND col.column_name='organization_id'
WHERE n.nspname='public'
AND c.relkind IN ('r','p')
AND pg_get_userbyid(c.relowner)=current_user
)
FROM pg_roles r
WHERE r.rolname=current_user
`, expectedRole).Scan(¤tUser, &sessionUser, &superuser, &bypassRLS, &member, &ownsTenantTable)
if err != nil {
return fmt.Errorf("postgres: inspect runtime identity: %w", err)
}
return validateRuntimeIdentity(currentUser, sessionUser, expectedRole, superuser, bypassRLS, member, ownsTenantTable)
}
func validateRuntimeIdentity(currentUser, sessionUser, expectedRole string, superuser, bypassRLS, member, ownsTenantTable bool) error {
// A safe SET ROLE is not a safe login: session_user may execute SET ROLE
// NONE later and recover its original privileges. Runtime pools therefore
// require the authenticated identity and effective identity to be identical.
if currentUser != sessionUser {
return fmt.Errorf("postgres: runtime current_user %q differs from session_user %q", currentUser, sessionUser)
}
if superuser || bypassRLS || ownsTenantTable {
return fmt.Errorf("postgres: unsafe runtime identity %q (session_user=%q superuser=%t bypassrls=%t owns_tenant_table=%t)", currentUser, sessionUser, superuser, bypassRLS, ownsTenantTable)
}
if !member {
return fmt.Errorf("postgres: runtime identity %q is not a member of %q", currentUser, expectedRole)
}
return nilView on GitHub (pinned to 3ee70a1026)