What's Actually Happening
AWS EC2 instances are unreachable via SSH or HTTP. Connection timeouts occur, instances show unreachable status, or services are not accessible.
The Error You'll See
SSH timeout:
```bash ssh ec2-user@ec2-1-2-3-4.compute.amazonaws.com
ssh: connect to host ec2-1-2-3-4.compute.amazonaws.com port 22: Connection timed out ```
Instance unreachable:
```bash aws ec2 describe-instance-status --instance-ids i-1234567890
{ "InstanceStatuses": [{ "InstanceState": { "Name": "running" }, "InstanceStatus": { "Status": "impaired" } }] } ```
Why This Happens
- 1.Security group blocking - No inbound rule for port
- 2.Network ACL blocking - NACL denying traffic
- 3.Wrong security group - Instance in wrong security group
- 4.Public IP missing - Instance has no public IP
- 5.Instance crashed - Instance OS crashed
- 6.Key pair wrong - Wrong SSH key
- 7.VPC misconfiguration - Subnet or routing issue
Step 1: Check Instance Status
```bash aws ec2 describe-instances --instance-ids i-1234567890
aws ec2 describe-instance-status --instance-ids i-1234567890
# Check instance state: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].State.Name'
# Check public IP: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].PublicIpAddress'
# Console output: aws ec2 get-console-output --instance-id i-1234567890 ```
Step 2: Check Security Groups
```bash # List security groups: aws ec2 describe-security-groups --group-ids sg-1234567890
# Check inbound rules: aws ec2 describe-security-groups --group-ids sg-1234567890 --query 'SecurityGroups[0].IpPermissions'
# Add SSH rule: aws ec2 authorize-security-group-ingress \ --group-id sg-1234567890 \ --protocol tcp \ --port 22 \ --cidr 0.0.0.0/0
# Add HTTP rule: aws ec2 authorize-security-group-ingress \ --group-id sg-1234567890 \ --protocol tcp \ --port 80 \ --cidr 0.0.0.0/0
# Instance security groups: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].SecurityGroups' ```
Step 3: Check Network ACLs
```bash # List NACLs: aws ec2 describe-network-acls
# Check NACL rules: aws ec2 describe-network-acls --network-acl-id acl-1234567890
# Check subnet NACL: aws ec2 describe-network-acls --filters Name=association.subnet-id,Values=subnet-1234567890
# NACL rules should allow: # - Inbound: Allow port 22 from your IP # - Outbound: Allow ephemeral ports (1024-65535)
# Add NACL rule: aws ec2 create-network-acl-entry \ --network-acl-id acl-1234567890 \ --rule-number 100 \ --protocol 6 \ --port-range From=22,To=22 \ --cidr-block 0.0.0.0/0 \ --rule-action allow \ --egress false ```
Step 4: Check VPC and Subnet
```bash # Check instance subnet: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].SubnetId'
# Check subnet is public: aws ec2 describe-subnets --subnet-ids subnet-1234567890
# Check route table: aws ec2 describe-route-tables --filters Name=association.subnet-id,Values=subnet-1234567890
# Should have route to Internet Gateway: # 0.0.0.0/0 -> igw-xxx
# Check Internet Gateway: aws ec2 describe-internet-gateways --filters Name=attachment.vpc-id,Values=vpc-1234567890 ```
Step 5: Check Public IP
```bash # Check if instance has public IP: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].PublicIpAddress'
# Allocate Elastic IP: aws ec2 allocate-address
# Associate Elastic IP: aws ec2 associate-address --instance-id i-1234567890 --allocation-id eipalloc-1234567890
# Check auto-assign public IP: aws ec2 describe-subnets --subnet-ids subnet-1234567890 --query 'Subnets[0].MapPublicIpOnLaunch' ```
Step 6: Check Key Pair
```bash # Check key pair name: aws ec2 describe-instances --instance-ids i-1234567890 --query 'Reservations[0].Instances[0].KeyName'
# Verify local key: ls -la ~/.ssh/my-key.pem
# Correct permissions: chmod 400 ~/.ssh/my-key.pem
# Connect with specific key: ssh -i ~/.ssh/my-key.pem ec2-user@ec2-public-ip.compute.amazonaws.com ```
Step 7: Connect via Session Manager
```bash # If SSH blocked, use SSM: aws ssm start-session --target i-1234567890
# Check SSM agent: # In session: sudo systemctl status amazon-ssm-agent
# Check instance has SSM role: aws ec2 describe-iam-instance-profile-associations --filters Name=instance-id,Values=i-1234567890 ```
Step 8: Check Instance Connect
```bash # Use EC2 Instance Connect: aws ec2-instance-connect send-ssh-public-key \ --instance-id i-1234567890 \ --instance-os-user ec2-user \ --ssh-public-key file://~/.ssh/id_rsa.pub
# Then connect: ssh -i ~/.ssh/id_rsa ec2-user@ec2-public-ip.compute.amazonaws.com ```
Step 9: Check System Logs
```bash # Get console output: aws ec2 get-console-output --instance-id i-1234567890 --output text
# Check for: # - Boot errors # - SSH service status # - Network configuration # - Cloud-init errors
# Check system log in AWS Console: # EC2 -> Instances -> Instance -> Actions -> Monitor and troubleshoot -> Get system log ```
Step 10: Reboot or Recover
```bash # Reboot instance: aws ec2 reboot-instances --instance-ids i-1234567890
# Stop and start (changes public IP): aws ec2 stop-instances --instance-ids i-1234567890 aws ec2 start-instances --instance-ids i-1234567890
# Create AMI for recovery: aws ec2 create-image --instance-id i-1234567890 --name "Recovery-Image"
# Replace instance: # Launch new instance from AMI ```
AWS EC2 Instance Unreachable Checklist
| Check | Command | Expected |
|---|---|---|
| Instance status | describe-instance-status | Status: ok |
| Security groups | describe-security-groups | SSH port allowed |
| Network ACLs | describe-network-acls | Port allowed |
| Public IP | describe-instances | IP assigned |
| Route table | describe-route-tables | IGW route |
| Key pair | describe-instances | Correct key |
Verify the Fix
```bash aws ec2 describe-instance-status --instance-ids i-1234567890
ssh -i ~/.ssh/key.pem ec2-user@ec2-public-ip.compute.amazonaws.com
aws ec2 describe-security-groups --group-ids sg-1234567890 --query 'SecurityGroups[0].IpPermissions'
ping -c 3 ec2-public-ip.compute.amazonaws.com
curl -I http://ec2-public-ip.compute.amazonaws.com ```
Related Issues
- [Fix AWS EC2 Instance Not Starting](/articles/fix-aws-ec2-instance-not-starting)
- [Fix AWS S3 Access Denied Error](/articles/fix-aws-s3-access-denied-error)
- [Fix SSH Connection Refused](/articles/fix-ssh-connection-refused)