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

  1. Do not revoke env-var-derived roles via the API; change the role assignment in the environment configuration instead
  2. Check the role name against the env-var role prefix before revoking
  3. 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

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


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/af75afae46256226. Report an issue: GitHub.