apolloconfig/apollo · warning · AccessDeniedException
Forbidden operation. Caused by: 1.you don't have release per
Error message
Forbidden operation. Caused by: 1.you don't have release permission or 2. you don't have modification permission or 3. you have modification permission but branch has been released
What it means
AccessDeniedException (HTTP 403) from NamespaceBranchController delete-branch. Deletion is allowed only when canDelete is true: the user has ReleaseNamespace permission, OR (has ModifyNamespace permission AND the branch has never been released, i.e. loadLatestRelease returns null). If none of those hold the operation is forbidden with this enumerated-cause message.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceBranchController.java:116
}
@DeleteMapping(
value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}")
@ApolloAuditLog(type = OpType.DELETE, name = "NamespaceBranch.delete")
public void deleteBranch(@PathVariable String appId, @PathVariable String env,
@PathVariable String clusterName, @PathVariable String namespaceName,
@PathVariable String branchName) {
boolean hasModifyPermission = unifiedPermissionValidator.hasModifyNamespacePermission(appId,
env, clusterName, namespaceName);
boolean hasReleasePermission = unifiedPermissionValidator.hasReleaseNamespacePermission(appId,
env, clusterName, namespaceName);
boolean canDelete = hasReleasePermission || (hasModifyPermission && releaseService
.loadLatestRelease(appId, Env.valueOf(env), branchName, namespaceName) == null);
if (!canDelete) {
throw new AccessDeniedException(
"Forbidden operation. " + "Caused by: 1.you don't have release permission "
+ "or 2. you don't have modification permission "
+ "or 3. you have modification permission but branch has been released");
}
namespaceBranchService.deleteBranch(appId, Env.valueOf(env), clusterName, namespaceName,
branchName, userInfoHolder.getUser().getUserId());
}
@PreAuthorize(
value = "@unifiedPermissionValidator.hasModifyNamespacePermission(#appId, #env, #clusterName, #namespaceName)")
@PostMapping(
value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/merge")
@ApolloAuditLog(type = OpType.UPDATE, name = "NamespaceBranch.merge")
public ReleaseDTO merge(@PathVariable String appId, @PathVariable String env,View on GitHub (pinned to d95fc18d11)
Solutions
- Ask a user with ReleaseNamespace permission to delete the branch.
- If you only have modify rights, delete the branch before it has been released (loadLatestRelease must be null).
- Verify your role assignment on the app/env/cluster/namespace via the portal.
- Confirm the branch hasn't already been released (cause #3).
Example fix
// No code fix: this is an authorization gate. // Resolution: act as a user holding ReleaseNamespace permission, or delete before first release.
Defensive patterns
Strategy: try-catch
Try / catch
// Branch delete can 403 with the enumerated-cause message.
try {
portal.deleteBranch(appId, env, cluster, namespace, branch);
} catch (HttpClientErrorException.Forbidden e) {
// Inspect causes: lacks release permission, lacks modify permission, or branch already released.
if (branchHasBeenReleased) {
report("cannot delete: branch already released; ask a release-permission user");
} else {
report("insufficient permission to delete branch");
}
} Prevention
- Delete gray branches before they are released if you only hold modify rights.
- Have a ReleaseNamespace-permissioned user perform branch deletion.
- Check loadLatestRelease state before attempting delete.
- Surface the three enumerated causes to the end user.
When it happens
Trigger: DELETE /apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName} by a user who neither has release permission nor the (modify + unreleased-branch) combination.
Common situations: A modify-only user trying to delete a branch that already has a published release; a user with no namespace role at all; deleting a gray branch after it was merged/released.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Access is denied
- Forbidden operation. Caused by: 1.you don't have release per
- Assign role permission is required
- You don't have the permission to modify namespace: %s
- Parent namespace not found
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/ae890ca1cbc24e2e.
Report an issue: GitHub.