EC2 instance stopped or terminated unexpectedly
Instance no longer in Running state — Stopping/Stopped or Terminated
Focused incident mode — strips away everything but this runbook.
Symptoms
- Instance no longer in Running state — Stopping/Stopped or Terminated
- App traffic stops immediately, no shift to a replacement
- CloudWatch AWS/EC2 StatusCheckFailed metric goes flat
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
State and transition reason
aws ec2 describe-instances --instance-ids <INSTANCE-ID> --query 'Reservations[0].Instances[0].{State:State,Reason:StateTransitionReason,AZ:Placement.AvailabilityZone}'Spot interruption signal (if spot)
aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name InstanceInterruptionWarning --dimensions Name=InstanceId,Value=<INSTANCE-ID>
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- StateTransitionReason == Client.UserInitiated
- A scheduled-stop job or operator action ran around the StopTime
Confirm before fixing
aws ec2 describe-instances --instance-ids <INSTANCE-ID> --query 'Reservations[0].Instances[0].{Reason:StateTransitionReason,StopTime:StopTime}'Confirm the reason and time
Expected: Client.UserInitiated with a StopTime
Fix
aws ec2 start-instances --instance-ids <INSTANCE-ID>Restart the instance if the stop was unintended
Expected: RUNNING
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
aws ec2 describe-instances --instance-ids <INSTANCE-ID> --query 'Reservations[0].Instances[0].{State:State,Reason:StateTransitionReason}'Identify who/what stopped it
aws cloudtrail lookup-events --lookup-attributes AttributeKey=ResourceName,AttributeValue=<INSTANCE-ID> --lookup-attributes AttributeKey=EventName,AttributeValue=StopInstancesTrace the API call through CloudTrail (if enabled)
aws ec2 start-instances --instance-ids <INSTANCE-ID>Restore the instance for unintended stops
aws ec2 modify-instance-attribute --instance-id <INSTANCE-ID> --disable-api-termination --value trueLock it down with termination protection
Prevention
- Enable CloudTrail for EC2 management events so every stop/terminate is attributable.
- Enable disableApiTermination on critical singleton instances.
- Run spot workloads behind an ASG with a diversified allocation strategy.
- Alert on InstanceStateChange events in EventBridge and tag instances for their schedule.
Related runbooks
Same stack, same failure family — worth a skim.
SSH to the instance times out or connection refused
ec2 run-instances returns InsufficientInstanceCapacity
Load climbs but instance count stays flat
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.