DynamoDB AccessDeniedException — "not authorized to perform dynamodb:..."
TL;DR — Your IAM user/role doesn't have permission for the DynamoDB action on that resource. The message names the exact dynamodb: action and ARN — add that action for that resource ARN to the identity's IAM policy (and check for a Deny or a condition that blocks it).
What it means
AccessDeniedException: User: arn:aws:iam::123456789012:user/app is not authorized to
perform: dynamodb:Query on resource: arn:aws:dynamodb:us-east-1:123456789012:table/Orders
because no identity-based policy allows the dynamodb:Query actionIAM denied the call. The message is a checklist: it names the principal, the action, and the resource — all three must be allowed with no explicit Deny. The trailing clause names the policy type that denied access (identity-based policy, SCP, permissions boundary, session policy, …). DynamoDB returns it with HTTP status 400, and it's not retryable — the same request fails until the policy (or the identity) changes.
Why it happens
- The action isn't allowed — the policy grants
dynamodb:GetItembut you calledQuery, or it's missing entirely. - The resource ARN doesn't match — the policy allows
table/Ordersbut you're querying an index (needstable/Orders/index/*) or a different table. - An explicit
Denysomewhere (a permission boundary, SCP, or the policy itself) overrides the allow. - A policy condition isn't satisfied (
dynamodb:LeadingKeysfine-grained access, source IP, MFA). - Wrong credentials — the role you assumed isn't the one with access.
How to fix it
- Grant the exact action the message names, for the exact resource ARN. Include index ARNs (
.../index/*) when you query a GSI/LSI. - Check for an overriding Deny — permission boundaries and SCPs beat allows.
- Verify fine-grained conditions (
dynamodb:LeadingKeysetc.) actually match your request. - Confirm identity with
aws sts get-caller-identity— make sure it's the principal you think it is.
Example policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["dynamodb:Query", "dynamodb:GetItem", "dynamodb:PutItem"],
"Resource": [
"arn:aws:dynamodb:us-east-1:123456789012:table/Orders",
"arn:aws:dynamodb:us-east-1:123456789012:table/Orders/index/*"
]
}
]
}Open it in DynoTable
DynoTable resolves the same ~/.aws profile your CLI uses on every connection
(Connect an AWS account), so when you fix IAM or switch
profiles the app picks it up without a restart. Press ⌘P to open the
profile switcher and confirm which identity is active — the credential status dot
turns red with an inline Reconnect action when tokens lapse mid-session.
If your policy denies dynamodb:ListTables but allows reads on a named table,
DynoTable can still open that table directly: ⌘K → Open table by
name skips the list call and goes straight to GetItem/Query on the table
you type. Once access works, the visual query builder
derives Query-vs-Scan from your filter pills so you can prove the policy allows
the operation you need. If the error names a GSI/LSI ARN, grant dynamodb:Query
on table/YourTable/index/* — index permissions are a common miss when table-level
allows look correct.
Related errors
- The security token is invalid — bad/expired credentials (vs. valid creds without permission).
- Missing region in config
- Learn: Running DynamoDB Local — develop locally where IAM policies don't apply.
Sources
- Troubleshoot access denied error messages — IAM User Guide (verified 2026-07-13)
- Using IAM policy conditions for fine-grained access control — Amazon DynamoDB Developer Guide (verified 2026-07-13)
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide (verified 2026-07-13)