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

  1. Ask a user with ReleaseNamespace permission to delete the branch.
  2. If you only have modify rights, delete the branch before it has been released (loadLatestRelease must be null).
  3. Verify your role assignment on the app/env/cluster/namespace via the portal.
  4. 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

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

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/ae890ca1cbc24e2e. Report an issue: GitHub.