EC2 Instance Not Starting – How to Fix, Troubleshoot, and Prevent in Production
Your EC2 instance won’t start. Maybe it’s stuck in pending, maybe it went from running to stopped and refuses to come back, or maybe you’re staring at an InsufficientInstanceCapacity error wondering what AWS is trying to tell you. I’ve been there at 3 AM more times than I’d like to admit.
The fix depends entirely on why it’s not starting. This guide walks you through every scenario I’ve encountered in production—from the embarrassingly simple misconfigurations to the obscure capacity issues that make you question your career choices.
What Is the Problem?
When an EC2 instance fails to start, it typically manifests in one of these states:
Pending – The instance is trying to launch but can’t complete. This is the classic “EC2 instance stuck in pending” scenario. It might stay here for minutes before failing or timing out.
Stopped – You clicked “Start” but nothing happened, or it briefly flickered to pending before returning to stopped. This “EC2 instance fails to start after stop” pattern often indicates capacity issues or EBS problems.
Terminated – The instance launched and immediately died. This is often the most confusing because AWS sometimes cleans up the evidence before you can investigate.
Running but unreachable – Technically started, but SSH times out and your application isn’t responding. The “EC2 running but unreachable” problem is often the most confusing because the console shows everything is fine while your monitoring disagrees.
The AWS console doesn’t always give you a clear error message. You might see generic status check failures, or worse, nothing at all. That’s what makes this problem frustrating—the symptom is obvious (it’s not working), but the cause could be one of fifteen different things.
People search for “EC2 instance not starting” when they’re already in trouble. The instance was working yesterday. Nothing changed. Except something definitely changed, and now you need to figure out what.
Real Production Impact
Let me be direct about why this matters.
When an EC2 instance won’t start in production, you’re not just dealing with a technical problem. You’re dealing with:
Immediate service impact – If this instance handles traffic, your users are affected right now. If it’s part of an Auto Scaling group, the group might be thrashing—trying to launch replacements that also fail, burning through your scaling policies without actually recovering.
Cascading failures – That database replica that won’t start? Your primary is now handling all read traffic. That worker node that’s stuck? Your queue is backing up. Production systems are interconnected, and one stuck instance can trigger alerts across multiple services.
Hidden costs – Here’s one that catches people off guard. Your instance is stopped, but your EBS volumes are still attached and you’re still paying for them. If you have multiple gp3 volumes with provisioned IOPS, that “stopped” instance might be costing you $50/day while sitting there doing nothing. I’ve seen teams rack up thousands in charges on instances that failed to start during a scaling event and were never cleaned up.
Auto Scaling nightmares – This is where things get ugly. If your launch template or AMI has a problem, Auto Scaling will keep trying to launch instances, they’ll keep failing, and your desired capacity will never be met. Meanwhile, the healthy instances are getting hammered because the scale-out never actually happened.
During an incident, a failing EC2 instance isn’t just annoying—it’s actively making everything worse.
Beginner-Friendly Checks (Start Here)
If you’re new to AWS or this is your first time troubleshooting EC2, start with these checks. They cover the most common mistakes I see from engineers who are still learning the platform.
Check the Instance State Reason
Go to the EC2 console, select your instance, and look at the “State transition reason” in the details panel. AWS sometimes tells you exactly what went wrong:
Client.UserInitiatedShutdown– Someone (or something) stopped it intentionallyServer.InternalError– AWS-side problem, usually temporaryClient.InstanceInitiatedShutdown– The instance shut itself down (check your scripts)Server.InsufficientInstanceCapacity– AWS doesn’t have capacity for your instance type in that AZ
This field is your first clue. Don’t skip it.
Verify System Status Checks
In the console, check the “Status checks” tab. You’ll see two checks:
System status check – This is AWS infrastructure. If this fails, the problem is on AWS’s side—the underlying host is degraded. You can’t fix this yourself. Stop the instance and start it again to move it to a different host.
Instance status check – This is your instance. If this fails, the problem is inside your instance—OS issues, disk problems, or configuration errors.
If you see “Instance reachability check failed,” your OS probably isn’t responding. More on that later.
Pull the System Log for Boot Failures
If the instance never passes instance status checks, always pull the system log before replacing it. Go to Actions → Monitor and troubleshoot → Get system log.
Look for these common boot errors:
- Kernel panic – The kernel crashed during boot. Usually indicates a bad AMI or incompatible instance type.
- Unable to mount root fs – The root volume is corrupted or the device mapping is wrong.
- GRUB errors – Bootloader can’t find the kernel. Often happens after manual kernel updates gone wrong.
- Waiting for device – The instance is waiting for an EBS volume that isn’t attaching properly.
This log is your best diagnostic tool for instances that start but never become reachable. Don’t skip it.
Confirm the Instance Type Is Available
Not all instance types are available in all Availability Zones. If you’re trying to start an m5.xlarge in us-east-1a but AWS doesn’t have capacity there, you’ll get an InsufficientInstanceCapacity error.
Try launching the same instance type in a different AZ. If it works there, that’s your answer—capacity in the original AZ is exhausted.
Check Your AMI
A corrupted or deleted AMI will prevent your instance from starting. This happens more often than you’d think, especially if:
- Someone deregistered the AMI thinking it wasn’t in use
- The AMI was shared from another account and that sharing was revoked
- You’re using a marketplace AMI that was discontinued
Go to EC2 → AMIs and confirm your AMI still exists and is in the “available” state.
IAM Role and Instance Profile Issues
If your instance needs to assume an IAM role at launch (which most production instances do), problems with the instance profile can prevent startup.
Check that:
- The instance profile exists
- The IAM role exists and is attached to the profile
- The role’s trust policy allows
ec2.amazonaws.comto assume it
A common mistake is deleting an IAM role without realizing it was attached to running instances. Those instances will keep running, but if you stop and start them, they won’t come back up because the role is gone.
Security Group and Subnet Basics
Your instance needs a valid subnet and at least one security group. If the subnet was deleted or the security group was removed, launch will fail.
Also verify that your subnet has available IP addresses. I’ve seen VPCs with small CIDR blocks run out of IPs, causing new instances to fail silently.
Mid-Level DevOps Troubleshooting Approach
Once you’ve ruled out the beginner mistakes, it’s time to think more systematically. Here’s how I approach EC2 startup issues when the obvious checks don’t reveal the problem.
At this stage, you’re trying to determine whether the failure is compute, storage, or networking.
Read the EC2 Events
Every instance has an event history. Go to your instance → Actions → Monitor and troubleshoot → Get system log. But more importantly, check the EC2 Events in the EC2 dashboard.
Scheduled events like maintenance or retirement will show up here. If AWS is planning to retire your instance’s underlying host, you’ll see it in events—and that scheduled retirement can cause problems before the actual retirement date.
CloudWatch Metrics Tell a Story
Before the instance stopped working, what were the metrics doing?
Pull up CloudWatch and look at:
- CPUUtilization – Was it pegged at 100% before failure?
- StatusCheckFailed – When exactly did this start?
- EBSReadOps/EBSWriteOps – Did I/O stop before the instance became unreachable?
- NetworkPacketsIn – Did traffic stop flowing?
The timeline matters. If CPU was fine but EBS operations dropped to zero, your root volume probably failed. If network packets stopped but everything else looked normal, it’s a VPC or security group issue.
Suspect EBS Problems
EBS volume issues cause a surprising number of “instance won’t start” problems. Check:
Volume state – Is your root volume in the “available” state when it should be “in-use”? That’s a detachment problem.
Volume events – EBS volumes have their own event stream. Check for io1/io2 volumes that hit their throughput limits or gp2 volumes that exhausted burst credits.
Impaired volumes – A degraded EBS volume will show “impaired” status. Your instance will either fail to start or start but be extremely slow.
If you suspect the root volume, try detaching it, attaching it to a healthy instance as a secondary volume, and checking the filesystem. You might find a full disk or corrupted files.
Network Configuration Rabbit Holes
VPC networking issues can prevent instances from starting or make them unreachable after startup.
Check:
- Route table associations (is your subnet still routed to an internet gateway or NAT gateway?)
- Network ACLs (did someone add a deny rule?)
- The ENI (elastic network interface) attached to the instance—is it in the right subnet with the right security groups?
A particularly sneaky problem: if your instance has a public IP and the internet gateway was detached from the VPC, the instance might start but be completely unreachable.
Don’t Chase the Wrong Signal
Here’s something I tell junior engineers: your monitoring might be lying to you.
If CloudWatch shows the instance is running but your application monitoring says it’s down, the problem isn’t the instance—it’s the application. Don’t waste time troubleshooting EC2 when the real issue is that your application crashed after startup.
Similarly, if your load balancer health checks are failing but the instance is running, check the health check configuration before assuming the instance is broken.
On-Call Production Triage (Fast Recovery)
You’re on call. It’s 2 AM. An EC2 instance isn’t starting and your pager is going off. Here’s what to do in the first five minutes.
First 5-Minute Actions
- Confirm the scope – Is this one instance or multiple? If multiple instances are failing to start, you likely have a broader problem (capacity, networking, IAM).
- Check instance state and reason – Get the state transition reason from the console. This takes 30 seconds and might tell you exactly what’s wrong.
- Check status checks – System status vs instance status. If system status is failed, stop and start (not reboot) to migrate to a new host.
- Look at recent changes – Was there a deployment in the last hour? A Terraform apply? A manual change? Ask your team.
- Decide: recover or replace – Can you fix this instance, or should you replace it?
Stop/Start vs Reboot vs Replace
Important distinction: Reboot keeps the instance on the same underlying host, so it will not fix system status check failures. Only stop/start migrates the instance to new hardware.
Stop and start when:
- System status check failed (moves instance to new host)
- The instance has local state you need to preserve
- You’re debugging and need to keep the same instance for investigation
Replace the instance when:
- Instance status check failed and you don’t know why
- The instance is stateless and part of an Auto Scaling group
- You’ve tried stop/start twice and it’s still failing
- Time pressure is high and you need service restored now
For stateless workloads behind a load balancer, replacement is almost always faster than troubleshooting. Terminate the broken instance and let Auto Scaling launch a new one.
Safe Temporary Fixes
If you need to restore service while you investigate:
- Scale out – Add more instances to handle load while the problematic one is down
- Traffic shifting – Remove the failing AZ from your load balancer if multiple instances there are affected
- Fallback capacity – If you have reserved capacity in another region, consider failing over
- Reduce load – Enable rate limiting or shed non-critical traffic to reduce pressure on remaining instances
What NOT to Change During an Incident
- Don’t modify security groups unless you’re certain that’s the problem
- Don’t delete and recreate IAM roles
- Don’t update the launch template in the middle of a scale-out
- Don’t apply Terraform changes “just to see if it helps”
- Don’t terminate instances that might have useful logs you haven’t collected yet
Every change you make during an incident is something you’ll need to remember during the postmortem. Change one thing at a time, and document what you changed.
When to Escalate to AWS Support
If system status checks fail repeatedly across multiple AZs, or InsufficientInstanceCapacity errors persist for hours despite trying different instance types, open an AWS support case. At that point, this is no longer under your control—it’s an AWS infrastructure issue that requires their intervention.
Senior-Level Root Cause Patterns
After handling hundreds of “instance won’t start” incidents, patterns emerge. Here are the root causes I see most often in production environments.
Capacity Exhaustion
AWS doesn’t have infinite capacity. During major events (Black Friday, re:Invent, regional incidents), certain instance types in certain AZs run out. You’ll see InsufficientInstanceCapacity errors.
This hits harder if you’re using:
- Older generation instances (m4, c4)
- GPU instances (p3, g4dn)
- Bare metal instances
- Specific AZs that are popular in your region
Mitigation: Use capacity reservations for critical workloads, spread across multiple AZs, and use newer instance generations.
EBS Volume Corruption
The root volume gets corrupted. This happens due to:
- Forced stops during heavy I/O
- Filesystem errors that accumulate over time
- Impaired EBS volumes that degrade
When the instance tries to start, the kernel can’t mount the root volume, and you get a boot failure. The console might show “running” but the instance never passes status checks.
You can often recover by detaching the volume, mounting it on another instance, running fsck, and reattaching. But if this is happening repeatedly, your AMI or provisioning process has a problem.
Bad User Data Scripts
User data runs once at first boot (unless you configure otherwise). If your user data script has a bug that causes the instance to shut down or become unresponsive, you’ll see instances that launch and immediately fail.
Common mistakes:
- Scripts that call
shutdownon failure - Scripts that wait forever for a resource that doesn’t exist
- Scripts that consume all memory or CPU during initialization
Check /var/log/cloud-init-output.log on a rescued instance to see what user data did.
IAM Permission Changes
Someone updated an IAM policy. Now the instance can’t pull its configuration from S3, can’t register with your service discovery, or can’t access secrets it needs to start.
The instance “starts” from EC2’s perspective, but the application fails to initialize because it lacks permissions it used to have.
Audit IAM changes through CloudTrail. Look for PutRolePolicy, DeleteRolePolicy, or DetachRolePolicy events.
AMI Drift
Your AMI worked fine when you created it. But now:
- The kernel is incompatible with the instance type you’re trying to use
- A package that was installed is no longer available for updates
- The AMI was based on a marketplace image that changed
If you haven’t updated your AMI in months, try launching with a fresh base AMI and see if the problem goes away.
The “Nothing Changed” Lie
When teams tell me “nothing changed,” I check CloudTrail, deployment logs, and Terraform state. Something always changed. The change might not be obvious, and it might be in a different system that affects EC2 indirectly:
- A new firewall rule in a network appliance
- An updated SSL certificate that the instance can’t validate
- A secrets manager rotation that happened automatically
- An Auto Scaling policy that modified the launch template
Find the change. It’s there.
Architect-Level Prevention & Design Fixes
If you’re dealing with EC2 startup failures regularly, you have a design problem. Here’s how to architect systems that survive instance failures gracefully.
Assume Instances Will Fail
Don’t treat instance failure as exceptional. Treat it as expected. Every instance in your fleet should be:
- Replaceable – No instance should be special. If losing one instance breaks your service, you have a single point of failure.
- Stateless – Application state belongs in managed services (RDS, ElastiCache, S3), not on instance volumes.
- Automated – If an instance fails, automation should replace it without human intervention.
Use Auto Scaling Groups (Even for Single Instances)
Even if you only need one instance, put it in an Auto Scaling group with min=1, max=1, desired=1.
Why? Because Auto Scaling will automatically replace the instance if it fails health checks. You get self-healing infrastructure without writing any code.
Configure proper health checks—don’t just rely on EC2 status checks. Use ELB health checks that verify your application is actually responding.
Multi-AZ Everything
Spread your instances across at least two Availability Zones. When AZ-specific issues occur (capacity, networking, hardware problems), traffic shifts to healthy AZs automatically.
Your load balancer should have cross-zone load balancing enabled so traffic distributes evenly regardless of how many instances are in each AZ.
Immutable Infrastructure
Stop troubleshooting instances. Replace them.
With immutable infrastructure:
- You never SSH into production instances to “fix” things
- Every deployment is a new AMI or container image
- Instances that misbehave are terminated, not repaired
- You can always roll back to a known-good image
This approach eliminates entire categories of problems. You can’t have configuration drift if you never modify running instances.
Health-Based Replacement
Configure your Auto Scaling groups to replace unhealthy instances automatically:
HealthCheckType: ELB
HealthCheckGracePeriod: 300
Use a grace period that’s long enough for your application to start but short enough that you’re not waiting forever to detect failures.
Capacity Planning
If you’re hitting InsufficientInstanceCapacity errors regularly:
- Use On-Demand Capacity Reservations for baseline capacity
- Spread instance types across multiple generations (m5, m6i, m7i)
- Use instance type flexibility in Auto Scaling groups
- Consider Spot for non-critical workloads with proper interruption handling
AWS Best Practices Checklist
Use this checklist to audit your EC2 configuration and prevent startup failures.
Security
- [ ] IAM roles use least privilege (but have enough permissions to start)
- [ ] Instance profiles are attached before launch, not after
- [ ] Security groups allow necessary traffic (health checks, application ports)
- [ ] NACLs don’t block required traffic
- [ ] IMDSv2 is required (prevents token theft, but configure applications to support it)
Reliability
- [ ] Instances are in Auto Scaling groups (even single instances)
- [ ] Workloads span multiple Availability Zones
- [ ] Health checks verify application health, not just instance status
- [ ] Launch templates are version-controlled and tested
- [ ] AMIs are tested before deployment
Observability
- [ ] CloudWatch alarms on StatusCheckFailed
- [ ] CloudWatch alarms on Auto Scaling group capacity vs desired
- [ ] EC2 instance events are monitored
- [ ] CloudTrail logs are retained and searchable
- [ ] Application logs ship to centralized logging
Cost Optimization
- [ ] Stopped instances with attached EBS are monitored
- [ ] Failed Auto Scaling launches generate alerts
- [ ] Orphaned EBS volumes are cleaned up regularly
- [ ] Reserved capacity matches actual usage patterns
Automation
- [ ] Infrastructure is defined in code (Terraform, CloudFormation, CDK)
- [ ] AMIs are built automatically through CI/CD
- [ ] Instance replacement is automated through Auto Scaling
- [ ] Runbooks exist for common failure scenarios
- [ ] Changes are deployed through pipelines, not manual console actions
Interview Questions & Answers
These questions test whether you’ve actually dealt with EC2 issues in production or just read about them.
Question 1: An EC2 instance is stuck in “pending” state. How do you troubleshoot?
What interviewers are testing: Systematic troubleshooting approach, understanding of EC2 launch process.
Answer: First, check the state transition reason in the instance details—AWS often tells you exactly why. Common causes include InsufficientInstanceCapacity (try a different AZ or instance type), ENI attachment failures (subnet has no IPs or security group is invalid), or IAM issues (instance profile doesn’t exist). If there’s no clear error, check the EC2 service health dashboard and try launching a basic Amazon Linux instance in the same subnet to isolate whether it’s instance-specific or environmental.
Question 2: Your Auto Scaling group keeps launching instances that fail health checks. How do you fix this?
What interviewers are testing: Understanding of ASG health checks, ability to prevent cascading failures.
Answer: First, suspend the scaling processes to stop the launch-fail-terminate loop. Then investigate: is it the AMI, user data, or application configuration? Check cloud-init logs on a failed instance before it terminates (set the ASG to keep failed instances temporarily). Verify the health check endpoint is correct and the grace period is long enough for the application to start. Once fixed, update the launch template version, and resume scaling.
Question 3: An instance shows “running” in the console but fails all connectivity tests. What do you check?
What interviewers are testing: Knowledge of EC2 networking, difference between EC2 state and actual reachability.
Answer: Running just means the hypervisor started the VM—it doesn’t mean the OS booted or the network is working. Check instance status checks (instance status failure means OS/kernel issues). Verify security groups allow your traffic. Check the route table for the subnet—is there a path to the internet or your source? Verify NACLs aren’t blocking. For SSH specifically, confirm the key pair matches and the instance has a public IP or you’re routing through a bastion. Get the system log to see if the OS is actually booting.
Question 4: How would you design an EC2-based application to survive instance startup failures?
What interviewers are testing: Architectural thinking, understanding of resilience patterns.
Answer: Use Auto Scaling groups with instances in multiple AZs and behind a load balancer with health checks. Make instances stateless so any instance can handle any request. Use immutable AMIs—never modify running instances. Configure the ASG to use multiple instance types to avoid capacity issues. Set up capacity reservations for baseline load. Monitor ASG events and set alarms when desired capacity doesn’t match running capacity. For data, use managed services like RDS with Multi-AZ rather than self-managed databases on EC2.
Question 5: You’re on call and get paged for an EC2 instance that won’t start. Walk me through your first five minutes.
What interviewers are testing: Incident response process, prioritization under pressure.
Answer: First 30 seconds: check if this is one instance or many, and whether it’s affecting production traffic. If traffic is affected and this is a stateless instance behind a load balancer, immediately scale out or remove the unhealthy AZ from the target group to restore service. Then investigate: check state transition reason, check status checks, check for recent changes (deployments, IAM changes, Terraform applies). If it’s a system status failure, stop and start to migrate hosts. If I can’t quickly identify the cause and this is a replaceable instance, terminate and let Auto Scaling replace it. Document everything for the postmortem.
Final Engineer Takeaway
The most important thing I’ve learned about EC2 startup failures: the instance not starting is a symptom, not the problem.
The real problem is usually something you changed, something AWS changed, or something that degraded silently over time. Your job isn’t to “fix the instance”—it’s to find and fix the underlying cause so it doesn’t happen again.
In production, speed matters. If you’re not sure whether to troubleshoot or replace, replace. A new instance from a known-good AMI will tell you whether the problem is instance-specific or systemic. You can always investigate the broken instance later.
Design your systems assuming instances will fail to start. Use Auto Scaling, spread across AZs, make everything replaceable. The engineers who sleep well during on-call rotations are the ones whose systems recover automatically.
When the pager goes off at 3 AM for an instance that won’t start, you want your first thought to be “Auto Scaling will handle this” not “I hope I remember how to fix this.”
Build systems that don’t need you. That’s the real fix.
