weaviate/weaviate · error
revoking: %w
Error message
revoking: %w
What it means
Wraps a failure from validateEnvVarRoles when revoking a role from a user: the role name refers to a reserved ENV VAR-managed role (name beginning with the env-var role prefix) that cannot be revoked via this endpoint. Returned as HTTP 403 Forbidden. The inner error details the offending role.
Source
Thrown at adapters/handlers/rest/authz/handlers_authz.go:1317
"component": authorization.ComponentName,
"user": principal.Username,
"role_to_get_users_for": params.ID,
}).Info("users requested")
return authz.NewGetUsersForRoleDeprecatedOK().WithPayload(filteredUsers)
}
func (h *authZHandlers) revokeRoleFromUser(params authz.RevokeRoleFromUserParams, principal *models.Principal) middleware.Responder {
ctx := params.HTTPRequest.Context()
internalID := namespacing.QualifyUserIDForLookup(principal, h.namespacesEnabled, params.ID)
for _, role := range params.Body.Roles {
if strings.TrimSpace(role) == "" {
return authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("one or more of the roles you want to revoke is empty")))
}
if err := validateEnvVarRoles(role); err != nil {
return authz.NewRevokeRoleFromUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("revoking: %w", err)))
}
}
if err := h.validateUserIDForNamespaces(internalID); err != nil {
return authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
if err := h.validateUserTypeForNamespaces(params.Body.UserType); err != nil {
return authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}
if len(params.Body.Roles) == 0 {
return authz.NewRevokeRoleFromUserBadRequest().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, fmt.Errorf("roles can not be empty")))
}
if err := h.authorizer.Authorize(ctx, principal, authorization.USER_AND_GROUP_ASSIGN_AND_REVOKE, authorization.Users(internalID)...); err != nil {
return authz.NewRevokeRoleFromUserForbidden().WithPayload(cerrors.ErrPayloadFromSingleErr(principal, err))
}View on GitHub (pinned to 75aa4b6d11)
Solutions
- Do not revoke env-var-derived roles via the API; change the role assignment in the environment configuration instead
- Check the role name against the env-var role prefix before revoking
- Filter dynamic roles out of the revoke request
Example fix
// before
roles := []string{"admin", dynamicRole} // dynamicRole like "env:xyz"
// after
if validateEnvVarRoles(dynamicRole) == nil {
roles = []string{"admin", dynamicRole}
} else {
roles = []string{"admin"} // manage dynamic role via env config
} Defensive patterns
Strategy: validation
Validate before calling
if strings.HasPrefix(role, envVarRolePrefix) {
return fmt.Errorf("role %q is env-var managed and cannot be revoked via API", role)
} Type guard
func isEnvVarRole(role string) bool { return strings.HasPrefix(role, envVarRolePrefix) } Prevention
- Filter dynamic/env-var roles out of revoke requests
- Manage env-var role assignments in configuration, not via RBAC APIs
- Document which roles in your deployment are env-var derived
When it happens
Trigger: POST /users/{id}/roles/revoke with a role name that matches the dynamic/env-var role naming convention (e.g. starts with the ENV_VAR prefixed dynamic role prefix), which is assignment-managed by environment configuration, not the RBAC API.
Common situations: Operators copying dynamic role names from GET /roles output and trying to revoke them directly; migrations that list all roles including env-var-generated ones; mixed static/dynamic deployments where some roles come from AUTHORIZATION_ADMIN env settings.
Related errors
- revoking roles from groups is not allowed
- assigning: %w
- one or more of the roles you want to revoke is empty
- one or more of the request roles doesn't exist
- username to revoke role from doesn't exist
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/af75afae46256226.
Report an issue: GitHub.