AWS Error Guide: 'KMSInvalidStateException' — Fix a Disabled or Pending-Deletion KMS Key
Fix AWS KMS KMSInvalidStateException and DisabledException: re-enable disabled keys, cancel scheduled deletion, and repair failing encrypt or decrypt calls.
- #aws
- #cloud
- #troubleshooting
- #errors
Stuck on this AWS with AI error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
AWS KMS keys have a lifecycle state — Enabled, Disabled, PendingDeletion, PendingImport, or Unavailable. Cryptographic operations (Encrypt, Decrypt, GenerateDataKey, ReEncrypt) only succeed when the key is Enabled. Calling one against a key in any other state fails with KMSInvalidStateException, and the specific DisabledException when the key is simply switched off. Because so many services (S3 SSE-KMS, EBS, RDS, Secrets Manager, Lambda env vars) decrypt through KMS transparently, this error surfaces far from the key itself.
You will see it from the CLI or SDK:
An error occurred (KMSInvalidStateException) when calling the Decrypt operation: arn:aws:kms:us-east-1:REDACTED:key/REDACTED is pending deletion.
The disabled-key variant is phrased slightly differently:
An error occurred (DisabledException) when calling the GenerateDataKey operation: arn:aws:kms:us-east-1:REDACTED:key/REDACTED is disabled.
It occurs whenever a key someone disabled or scheduled for deletion is still referenced by a live workload — an S3 bucket’s default encryption key, an EBS volume’s key, a Secrets Manager secret, or a Lambda’s environment encryption key.
Symptoms
KMSInvalidStateExceptiononDecrypt/GenerateDataKeywith a message endingis disabled,is pending deletion, oris not enabled.- S3
GetObjectreturnsKMS.DisabledExceptioneven though the object exists and IAM allows access. - EC2 instances backed by an encrypted AMI/EBS fail to launch with a state error on the volume’s key.
- Secrets Manager
GetSecretValueor an RDS start fails referencing the KMS key.
aws s3 cp s3://REDACTED-bucket/report.parquet .
fatal error: An error occurred (KMS.DisabledException) when calling the GetObject operation: arn:aws:kms:...:key/REDACTED is disabled
aws kms describe-key --key-id alias/app-data --query 'KeyMetadata.[KeyState,DeletionDate]' --output text
PendingDeletion 2026-07-16T00:00:00+00:00
Common Root Causes
1. The key was manually disabled
Someone disabled the key during a security review or cleanup, not realizing a workload still used it.
aws kms describe-key --key-id alias/app-data --query 'KeyMetadata.KeyState' --output text
Disabled
Disabled is fully reversible — re-enabling restores access immediately with no data loss.
2. The key is scheduled for deletion
A key put into PendingDeletion has a 7–30 day waiting period. During that window crypto operations fail, and if the window elapses the key — and the ability to decrypt anything under it — is gone permanently.
aws kms describe-key --key-id alias/app-data \
--query 'KeyMetadata.[KeyState,DeletionDate]' --output text
PendingDeletion 2026-07-16T00:00:00+00:00
Cancel deletion before that date; after it, the data is unrecoverable.
3. Imported key material expired or was deleted
For keys with Origin=EXTERNAL, the imported material can expire or be deleted, leaving the key PendingImport / Unavailable.
aws kms describe-key --key-id REDACTED \
--query 'KeyMetadata.[Origin,KeyState,ExpirationModel,ValidTo]' --output text
EXTERNAL PendingImport KEY_MATERIAL_EXPIRES 2026-07-01T00:00:00+00:00
The material must be re-imported before the key works again.
4. A regional or multi-Region replica mismatch
Code targets a Region where the key does not exist or its replica is not yet enabled, so the resolved key is in the wrong state.
aws kms describe-key --key-id alias/app-data --region eu-west-1 \
--query 'KeyMetadata.[MultiRegion,KeyState]' --output text
True Disabled
The primary may be enabled while the replica in the calling Region is disabled.
5. A grant or key policy left the key usable only in a state you changed
Automation that disables keys on a schedule (e.g. a “disable unused keys” control) caught a key that is actually in use.
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=DisableKey \
--query 'Events[].[EventTime,Username]' --output text
2026-07-08T02:11:00Z key-hygiene-bot
key-hygiene-bot disabled the key — the automation, not a human, is the cause.
Diagnostic Workflow
Step 1: Identify the exact key and its state
aws kms describe-key --key-id <alias-or-arn> \
--query 'KeyMetadata.[KeyId,KeyState,DeletionDate,Origin,MultiRegion]' --output text
The KeyState tells you which fix applies: Disabled → re-enable, PendingDeletion → cancel deletion, PendingImport → re-import material.
Step 2: Confirm you are in the right Region
aws configure get region
aws kms list-aliases --query "Aliases[?AliasName=='alias/app-data'].[TargetKeyId]" --output text
A key is Regional; make sure the failing call and the key are in the same Region.
Step 3: Find who changed the state and when
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue=<KEY_ID> \
--query 'Events[?contains(EventName,`Disable`)||contains(EventName,`ScheduleKeyDeletion`)].[EventTime,EventName,Username]' \
--output text
This shows whether a human or an automation disabled or scheduled deletion, and when the deletion window ends.
Step 4: Confirm what still depends on the key
aws kms list-grants --key-id <KEY_ID> --query 'Grants[].GranteePrincipal' --output text
aws s3api get-bucket-encryption --bucket REDACTED-bucket \
--query 'ServerSideEncryptionConfiguration.Rules[].ApplyServerSideEncryptionByDefault' 2>/dev/null
Verify which resources point at this key before re-enabling, so you understand the blast radius.
Example Root Cause Analysis
A nightly report job began failing on s3 cp with KMS.DisabledException. The bucket used SSE-KMS with a customer-managed key.
describe-key showed the key was Disabled, not deleted:
aws kms describe-key --key-id alias/reports --query 'KeyMetadata.KeyState' --output text
Disabled
CloudTrail pinned the cause to an automation run earlier that night:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=DisableKey \
--query 'Events[0].[EventTime,Username]' --output text
2026-07-08T02:11:00Z key-hygiene-bot
A “disable keys with no recent use” hygiene job had counted 30 days of no direct KMS calls, not realizing S3 decrypts lazily only when objects are read. Re-enabling restored access instantly:
aws kms enable-key --key-id alias/reports
aws s3 cp s3://REDACTED-bucket/report.parquet . && echo "OK"
The durable fix was excluding keys attached to S3/EBS/Secrets from the hygiene bot’s disable list, keying the “unused” check on resource attachment rather than direct API calls.
Prevention Best Practices
- Never let key-hygiene automation disable or schedule deletion of keys that are still referenced by S3, EBS, RDS, or Secrets Manager; check attachments, not just recent direct calls.
- Enable a CloudWatch alarm on the KMS
DisableKeyandScheduleKeyDeletionevents so a state change is noticed within minutes, not at the next failed job. - Set the maximum 30-day deletion waiting period on important keys so there is time to catch and cancel an accidental schedule.
- Use key aliases and resource policies rather than raw key IDs so a key rotation or replacement does not silently point workloads at a wrong-state key.
- For multi-Region keys, verify the replica in every Region you operate in is
Enabled, not just the primary.
Quick Command Reference
# Show the key's state and deletion date
aws kms describe-key --key-id <alias-or-arn> \
--query 'KeyMetadata.[KeyState,DeletionDate,Origin]' --output text
# Re-enable a disabled key
aws kms enable-key --key-id <alias-or-arn>
# Cancel a scheduled deletion (before the DeletionDate)
aws kms cancel-key-deletion --key-id <KEY_ID>
aws kms enable-key --key-id <KEY_ID>
# Find who disabled or scheduled deletion
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=ResourceName,AttributeValue=<KEY_ID> \
--query 'Events[].[EventTime,EventName,Username]' --output text
# Confirm Region alignment
aws configure get region; aws kms list-aliases --query "Aliases[].AliasName"
Conclusion
KMSInvalidStateException / DisabledException means the key exists but is not in a usable state. The usual root causes:
- The key was manually disabled and is still in use.
- The key is scheduled for deletion inside its waiting period.
- Imported external key material expired or was deleted.
- The call targets a Region where the key or its replica is disabled/absent.
- Hygiene automation disabled a key that a service still decrypts through lazily.
Read KeyState first, then apply the matching fix — enable-key for disabled, cancel-key-deletion for pending deletion, re-import for external material — and act before any DeletionDate passes, because after it the data under that key is gone for good.
Fixed it? Get 500 AWS with AI & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.