Fix a permission denial on Google Cloud — the order to check things in

Seven steps, in the order that answers fastest: read the three facts off the error, retry once for eventual consistency, run Policy Troubleshooter, rule out deny and boundary policies, check whether the permission needs actAs, then grant the narrowest predefined role. Ends with the three things never to do.

markdownguidev1MHSM-NJWZstage: operatetrust: officialfamily: identityservice: iaminterface: clipermission denied403access deniedpolicy troubleshooteractAsdeny policyiam bindingadd-iam-policy-binding

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Fix a permission denial

Step 1 — read three facts off the error, then retry once

A Google Cloud permission error carries an error ID whose context is "the principal, resource, permission". Those three are the whole input to every step below. Write them down before you touch a policy.

Then retry the identical call once. The IAM API is eventually consistent and a recent grant "might take time to affect access checks". A single retry costs nothing and resolves a measurable share of denials with no change at all.

Step 2 — ask the platform why, instead of guessing

gcloud beta policy-intelligence troubleshoot-policy iam RESOURCE \
    --principal-email=EMAIL --permission=PERMISSION

PERMISSION is the service.resource.verb string from the error, not a role. The tool evaluates allow policies, deny policies and Principal Access Boundary policies together, which is the only way to see an interaction between them.

If the answer is Unknown, stop. It means the principal running the diagnosis cannot read one of the policies involved. It does not mean the policy is absent. Re-run as a principal that can read the organization's policies.

Step 3 — is a role missing, or is one being cancelled?

The page's rule: "all policy types must permit access." So there are two different repairs and they look the same from the caller's side:

Troubleshooter saysRepair
no allow policy grants itadd a role binding (step 6)
a deny policy blocks itthe binding will not help — deny overrides allow. The deny policy must change, and that is almost always somebody else's decision
a Principal Access Boundary makes the resource ineligiblesame: an outer policy, not yours to widen
a conditional binding evaluated falseread the condition. The usual causes are a time window, a resource-name prefix, or a tag the resource does not carry
group membership unverifiablethe principal is in a group the evaluator cannot resolve; bind the principal directly to test, then fix the group

Three of those five are refusals working as intended. Widening them is operator-hand work, not a fix.

Step 4 — check the inherited grants before you add one at the leaf

Policy inherits down the hierarchy: organization → folder → project → resource. A principal may already hold the role one level up, in which case your failure is not the one you think it is. Look upward before adding a binding at the leaf — and remember that nothing at a child level can take a parent's grant away.

Step 5 — the actAs class, which is not a missing role on the resource

If the permission in the error is about a service account rather than about the resource you were touching — anything of the iam.serviceaccounts.* shape — the denial is about identity attachment:

You are trying toRole the caller needs
create a resource that runs as a service accountroles/iam.serviceAccountUser on that service account
mint a credential as a service accountroles/iam.serviceAccountTokenCreator on it

They are different grants on a different object (the service account's own allow policy, not the project's). A Cloud Run deploy failing with "User does not have permission to access namespace" is usually this.

Step 6 — grant the narrowest predefined role, at the narrowest scope

Find the role that carries the permission (reference/identity/predefined-roles-and-permissions.md), then bind it as low in the hierarchy as the caller's work allows — on the bucket, not the project; on the project, not the folder.

Step 7 — confirm, and record what it was

Re-run the original call. Then record which permission was missing: a migration estimate's accuracy depends on this list existing (guides/parity-and-migration-method.md uses it as an input).

Never

  1. Never grant a basic role (Owner, Editor, Viewer) to close a denial. The IAM overview calls them

"highly permissive, unsuitable for production" and they grant every service rather than the one that failed.

  1. Never write the policy twice on the first failure. The second read-modify-write on a stale etag is how

an unrelated binding disappears.

  1. Never answer a 401 authError with a role grant. That one is the credential, not the policy.

Read this document as markdown — the same bytes an agent receives.