Home / AWS

AWSTroubleshootingAdvanced

KMS AccessDeniedException and disabled keys: fixing encrypted resource failures

When EBS volumes won't attach, instances won't start or S3 and RDS reads fail with KMS errors, check the key policy, grants, key state and cross-account setup.

Deepak Bhardwaj3 min read

Applies toAWS KMS customer managed keys, EBS, S3, RDS, Secrets Manager

Symptoms that are really KMS

What the customer sees Hidden KMS issue
EC2 instance goes from pending straight to stopped The encrypted root volume's key is disabled, or the caller can't use it (Client.InternalError in the state reason)
Auto Scaling launches fail The service-linked role isn't allowed to use the key
S3 GetObject 403 Missing kms:Decrypt on the SSE-KMS key
Secrets Manager AccessDeniedException The secret uses a CMK the caller can't decrypt with
aws ec2 describe-instances --instance-ids i-0abc --query "Reservations[].Instances[].StateReason"

1. What state is the key in?

aws kms describe-key --key-id arn:aws:kms:ap-south-1:111122223333:key/1234abcd-... \
  --query "KeyMetadata.{state:KeyState,enabled:Enabled,manager:KeyManager,deletion:DeletionDate}"
State Action
Disabled aws kms enable-key --key-id <id>, after confirming it was disabled by mistake
PendingDeletion aws kms cancel-key-deletion --key-id <id>, then enable it. Do this within the waiting period, because deleted keys can't be recovered and neither can the data.
PendingImport / unavailable Imported key material expired, or the custom key store is disconnected

2. Key policy (the primary control)

aws kms get-key-policy --key-id <id> --policy-name default --output text | python3 -m json.tool
  • The key policy must allow the principal, or delegate to IAM with the statement allowing the account root (arn:aws:iam::111122223333:root) kms:*. Only then do IAM policies count.
  • For EBS through Auto Scaling, the key must allow the AWSServiceRoleForAutoScaling role to CreateGrant, Decrypt, GenerateDataKey*, ReEncrypt* and DescribeKey.

3. Find the denied call

aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventSource,AttributeValue=kms.amazonaws.com \
  --max-results 50 --query "Events[].CloudTrailEvent" --output text \
  | jq -r 'select(.errorCode != null) | [.eventTime, .eventName, .userIdentity.arn, .errorCode] | @tsv'

The userIdentity.arn is often a service role you didn't expect (EBS, Auto Scaling, RDS) acting on the user's behalf.

4. Cross-account use

Both sides must allow it:

  1. The key policy in account A allows account B's principal (or the account B root).
  2. The IAM policy in account B allows kms:Decrypt and the other needed actions on the key ARN.
  3. AWS-managed keys (aws/ebs, aws/s3) can't be shared across accounts. Re-encrypt with a customer managed key before sharing snapshots or AMIs.

5. Conditions that silently deny

  • kms:ViaService limits use to a specific service, for example s3.ap-south-1.amazonaws.com.
  • kms:EncryptionContext:* must match exactly what the service sends.
  • aws:SourceVpce in the key policy blocks calls that don't come through the VPC endpoint.

Prevent it next time

  • Protect keys from accidental deletion: limit kms:ScheduleKeyDeletion with SCPs, and use the maximum 30-day waiting period.
  • Alarm (EventBridge) on DisableKey and ScheduleKeyDeletion events.
  • Keep key policies in IaC, next to the resources that use them.