apolloconfig/apollo · error · AccessDeniedException
Create namespace permission is required
Error message
Create namespace permission is required
What it means
HTTP 403 (AccessDeniedException). Thrown by NamespaceController.requireCreateNamespacePermissionForUserToken: auth type USER_TOKEN and UnifiedPermissionValidator.hasCreateNamespacePermission(appId,env,cluster,namespace) is false. The user-token lacks the create-namespace permission required to add a namespace under the app/cluster. This gate runs for every namespace in a batch create and on single creates.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/NamespaceController.java:387
if (!UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
|| CollectionUtils.isEmpty(namespaces)) {
return;
}
for (OpenCreateNamespaceDTO namespace : namespaces) {
if (namespace == null || StringUtils.isBlank(namespace.getAppId())) {
continue;
}
requireCreateNamespacePermissionForUserToken(namespace.getAppId(), namespace.getEnv(),
namespace.getClusterName(), namespace.getAppNamespaceName());
}
}
private void requireCreateNamespacePermissionForUserToken(String appId, String env,
String clusterName, String namespaceName) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasCreateNamespacePermission(appId, env, clusterName,
namespaceName)) {
throw new AccessDeniedException("Create namespace permission is required");
}
}
private void requireDeleteNamespacePermissionForUserToken(String appId, String env,
String clusterName, String namespaceName) {
if (UserIdentityConstants.USER_TOKEN.equals(UserIdentityContextHolder.getAuthType())
&& !unifiedPermissionValidator.hasDeleteNamespacePermission(appId, env, clusterName,
namespaceName)) {
throw new AccessDeniedException("Delete namespace permission is required");
}
}
private String resolveOperator(String queryOperator, String payloadOperator) {
String authType = UserIdentityContextHolder.getAuthType();
if (UserIdentityConstants.USER.equals(authType)
|| UserIdentityConstants.USER_TOKEN.equals(authType)) {
UserInfo loginUser = userInfoHolder.getUser();
if (loginUser == null || StringUtils.isBlank(loginUser.getUserId())) {View on GitHub (pinned to d95fc18d11)
Solutions
- Grant the user-token owner CreateNamespace permission on the target appId/env/cluster (and app-namespace if required).
- Remove the unauthorized entry from the batch and retry the rest.
- Use a portal USER with create-namespace rights or a CONSUMER token scoped for namespace creation.
- Pre-check hasCreateNamespacePermission per entry before submitting the batch.
Example fix
// before: user-token owner lacks CreateNamespace on appX
client.withUserToken(token).createNamespace("appX", env, cluster, dto); // 403
// after: grant create-namespace then retry
admin.grantCreateNamespace("appX", env, cluster, token.getOwnerId());
client.withUserToken(token).createNamespace("appX", env, cluster, dto); Defensive patterns
Strategy: validation
Validate before calling
// For USER_TOKEN namespace create: confirm CreateNamespace permission per target.
for (OpenCreateNamespaceDTO n : namespaces) {
if (!hasCreateNamespace(tokenOwner, n.getAppId(), n.getEnv(), n.getClusterName())) {
// grant or drop this entry; do not submit it
}
} Type guard
null
Try / catch
try {
client.withUserToken(token).createNamespaces(namespaces);
} catch (HttpServerErrorException.Forbidden e) {
// Create namespace permission is required -> grant CreateNamespace and retry
} Prevention
- Grant CreateNamespace to automation tokens that provision namespaces.
- Pre-check create permission per batch entry to avoid partial failures.
- Keep create vs modify roles distinct; create is typically more privileged.
When it happens
Trigger: POST create namespace(s) on NamespaceController using a user-token whose owner lacks CreateNamespace role on the target app/env/cluster (or the specific app-namespace name). Fires per-entry in batch creation.
Common situations: User-token provisioned with modify but not create-namespace rights; creating a private/link namespace that requires an additional grant; batch create where one entry targets an app the owner cannot create in.
Related errors
- Access is denied
- Delete namespace permission is required
- You don't have the permission to modify namespace: %s
- Access is denied
- Metadata read permission is required
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/7ed4d52e5d544022.
Report an issue: GitHub.