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. 1.Security group blocking - No inbound rule for port
  2. 2.Network ACL blocking - NACL denying traffic
  3. 3.Wrong security group - Instance in wrong security group
  4. 4.Public IP missing - Instance has no public IP
  5. 5.Instance crashed - Instance OS crashed
  6. 6.Key pair wrong - Wrong SSH key
  7. 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

CheckCommandExpected
Instance statusdescribe-instance-statusStatus: ok
Security groupsdescribe-security-groupsSSH port allowed
Network ACLsdescribe-network-aclsPort allowed
Public IPdescribe-instancesIP assigned
Route tabledescribe-route-tablesIGW route
Key pairdescribe-instancesCorrect 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 ```

  • [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)