weaviate/weaviate · critical
RBAC is expected to be enabled, but the controller wasn't in
Error message
RBAC is expected to be enabled, but the controller wasn't initialized
What it means
A startup sanity check in configureAuthorizer: RBAC is enabled in config but `appState.RBAC` was never assigned, meaning the rbac.New branch either didn't run or failed to assign the controller. Weaviate treats this as an invariant violation and refuses to start, because serving requests with RBAC enabled but no enforcer would silently bypass authorization.
Source
Thrown at adapters/handlers/rest/configure_server.go:190
appState.NamespacesController,
appState.Logger)
if err != nil {
return fmt.Errorf("can't init casbin %w", err)
}
appState.AuthzController = rbacController
appState.RBAC = rbacController
appState.Authorizer = rbacController
} else if appState.ServerConfig.Config.Authorization.AdminList.Enabled {
appState.Authorizer = adminlist.New(appState.ServerConfig.Config.Authorization.AdminList)
} else {
appState.Authorizer = &authorization.DummyAuthorizer{}
}
if appState.ServerConfig.Config.Authorization.Rbac.Enabled && appState.RBAC == nil {
// this in general shall not happen, it's to catch cases were RBAC expected but we weren't able
// to assign it.
return fmt.Errorf("RBAC is expected to be enabled, but the controller wasn't initialized")
}
return nil
}
func timeTillDeadline(ctx context.Context) string {
dl, _ := ctx.Deadline()
return time.Until(dl).String()
}
View on GitHub (pinned to 75aa4b6d11)
Solutions
- Look for a preceding "can't init casbin" error in the logs; fix that root cause — this guard is its downstream symptom.
- Confirm `authorization.rbac.enabled` matches intent; if you meant admin-list or no auth, correct the config.
- Ensure the RBAC controller assignment (appState.RBAC = rbacController) executes on every path where RBAC is enabled; rebuild from an unmodified release.
- If reproducible on a stock build, report with full startup logs and config (redact secrets).
Example fix
// before: enabled RBAC while pointing admin list on, masking the rbac branch
authorization:
rbac: { enabled: true }
admin_list: { enabled: true, users: [...] }
// after: single coherent authorization mode
authorization:
rbac: { enabled: true }
admin_list: { enabled: false } Defensive patterns
Strategy: validation
Validate before calling
// config sanity before startup: exactly one authorization mode, consistent flags
def validate_authz(cfg):
rbac = cfg['authorization']['rbac']['enabled']
admin = cfg['authorization']['admin_list']['enabled']
assert not (rbac and not rbac_supported()), "RBAC enabled but build/config path unavailable"
assert rbac or admin or cfg['authorization'].get('allow_anonymous'), "no authorizer mode configured" Prevention
- Keep RBAC and admin_list flags coherent — don't mix modes across partial config updates.
- Deploy stock release binaries; treat any local patch to configureAuthorizer as high-risk.
- On this error, immediately grep logs for the earlier 'can't init casbin' root cause.
- Run startup smoke tests in staging with the same authorization config as production.
When it happens
Trigger: `authorization.rbac.enabled=true` while configureAuthorizer returned from a different branch (e.g. rbac.New was skipped due to an internal condition, or an earlier wrapped failure left appState.RBAC nil before this guard ran). The comment in the source says this "in general shall not happen" — it catches partially failed initialization.
Common situations: Patched/custom builds where the RBAC assignment path was altered; config where both rbac and admin_list flags interact unexpectedly; race or partial failure during startupRoutine before the earlier rbac.New error could abort startup.
Related errors
- can't init casbin %w
- apply env config
- insufficient permissions to view role
- role grants a permission you do not hold
- unauthorized: namespaced OIDC principal cannot be granted th
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/b783f0d972e9ebef.
Report an issue: GitHub.