Introduction
EC2 Instance Connect allows SSH access to instances without managing SSH keys. When it fails, you can't connect to your instance through the browser-based SSH or the Instance Connect CLI, even though the instance is running and reachable.
Symptoms
In the AWS Console:
Failed to connect to your instance
Error establishing SSH connection. The SSH key was not found or is not authorized.Via AWS CLI:
```bash $ aws ec2-instance-connect send-ssh-public-key --instance-id i-abc123 --availability-zone us-east-1a --instance-os-user ec2-user --ssh-public-key file://my-key.pub
An error occurred (AuthException) when calling the SendSSHPublicKey operation: User is not authorized ```
Common Causes
- 1.Missing IAM permissions - User/role lacks
ec2-instance-connect:SendSSHPublicKey - 2.Security group blocking - Port 22 not open to Instance Connect IP ranges
- 3.Instance Connect endpoint missing - No endpoint in the VPC for private instances
- 4.Instance ID not found - Wrong instance ID or instance terminated
- 5.OS user doesn't exist - Specified user doesn't exist on the instance
- 6.Instance not running - Instance is stopped or terminated
- 7.Wrong availability zone - Zone mismatch in the request
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check IAM Permissions
The IAM user or role needs permission to push SSH keys:
```bash # Check your current identity aws sts get-caller-identity
# Verify permissions aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::123456789:user/myuser \ --action-names ec2-instance-connect:SendSSHPublicKey \ --resource-arns arn:aws:ec2:us-east-1:123456789:instance/i-abc123 ```
Required IAM policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2-instance-connect:SendSSHPublicKey",
"ec2:DescribeInstances"
],
"Resource": "*"
}
]
}Step 2: Verify Instance State
aws ec2 describe-instances --instance-ids i-abc123 \
--query 'Reservations[*].Instances[*].[State.Name,LaunchTime]'Instance must be in running state.
Step 3: Configure Security Group
Instance Connect uses IP ranges that vary by region. The security group must allow SSH (port 22) from these ranges:
# Get Instance Connect IP ranges for your region
curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq '.prefixes[] | select(.service=="EC2_INSTANCE_CONNECT") | select(.region=="us-east-1") | .ip_prefix'Add security group rule:
```bash # Get security group ID SG_ID=$(aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text)
# Add inbound SSH rule for Instance Connect (example for us-east-1) # Note: Add each IP range separately aws ec2 authorize-security-group-ingress \ --group-id $SG_ID \ --protocol tcp \ --port 22 \ --cidr 18.206.107.24/29 ```
For browser-based SSH, also allow:
- 13.107.42.0/24 (Microsoft Azure IP for browser)
- Your organization's public IP if using console
Step 4: Set Up Instance Connect Endpoint (for Private Instances)
For instances in private subnets without internet access:
# Create Instance Connect endpoint
aws ec2 create-instance-connect-endpoint \
--subnet-id subnet-12345 \
--security-group-id sg-12345Wait for endpoint to become available:
aws ec2 describe-instance-connect-endpoints \
--filters Name=state,Values=create-completeConnect through the endpoint:
aws ec2-instance-connect ssh \
--instance-id i-abc123 \
--instance-connect-endpoint-id eice-12345 \
--os-user ec2-userStep 5: Verify OS User Exists
```bash # Get instance OS from metadata aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].[PlatformDetails,ImageId]'
# Common OS users: # Amazon Linux 2: ec2-user # Ubuntu: ubuntu # Debian: admin or debian # RHEL: ec2-user or root # CentOS: centos # SUSE: ec2-user ```
If the user doesn't exist:
```bash # Connect via SSM if available aws ssm start-session --target i-abc123
# Create user sudo useradd -m -s /bin/bash myuser ```
Step 6: Push SSH Key Manually
```bash # Generate a key pair ssh-keygen -t rsa -b 2048 -f my-temp-key -N ""
# Push the public key aws ec2-instance-connect send-ssh-public-key \ --instance-id i-abc123 \ --availability-zone us-east-1a \ --instance-os-user ec2-user \ --ssh-public-key file://my-temp-key.pub
# Connect with private key ssh -i my-temp-key ec2-user@ec2-1-2-3-4.compute-1.amazonaws.com ```
Note: Keys pushed via Instance Connect are valid for 60 seconds.
Step 7: Check Instance Connect Agent
On the instance, verify Instance Connect is installed:
```bash # SSH via SSM or existing key # Check if EC2 Instance Connect is installed rpm -qa | grep ec2-instance-connect # Amazon Linux dpkg -l | grep ec2-instance-connect # Ubuntu
# If not installed, install it: # Amazon Linux 2 sudo yum install ec2-instance-connect -y
# Ubuntu sudo apt-get install ec2-instance-connect -y ```
Verify the service is running:
```bash # Check authorized_keys_command configuration cat /etc/ssh/sshd_config | grep AuthorizedKeysCommand
# Should show: # AuthorizedKeysCommand /opt/aws/bin/eic_run_authorized_keys %u %f # AuthorizedKeysCommandUser ec2-instance-connect ```
Step 8: Check Audit Logs
```bash # Check CloudTrail for Instance Connect events aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=SendSSHPublicKey \ --max-items 10
# Check instance console output aws ec2 get-console-output --instance-id i-abc123 --output text | grep -i ssh ```
Step 9: Test Connection
```bash # Using AWS CLI aws ec2-instance-connect ssh --instance-id i-abc123 --os-user ec2-user
# Using browser (console) # Navigate to EC2 Console > Instances > Select instance > Connect # Choose "EC2 Instance Connect" tab ```
Step 10: Troubleshoot Network ACLs
If security group is correct but connection still fails:
```bash # Get subnet's network ACL SUBNET_ID=$(aws ec2 describe-instances --instance-ids i-abc123 \ --query 'Reservations[*].Instances[*].SubnetId' --output text)
NACL_ID=$(aws ec2 describe-network-acls \ --filters Name=association.subnet-id,Values=$SUBNET_ID \ --query 'NetworkAcls[*].NetworkAclId' --output text)
# Check NACL rules aws ec2 describe-network-acls --network-acl-ids $NACL_ID \ --query 'NetworkAcls[*].Entries' ```
Ensure NACL allows: - Inbound TCP port 22 from Instance Connect IP ranges - Outbound ephemeral ports (1024-65535) to Instance Connect IP ranges
Verification
```bash # Test SSH connection aws ec2-instance-connect ssh --instance-id i-abc123 --os-user ec2-user --private-key-file ~/.ssh/my-key
# Should open SSH session successfully ```
Related Issues
- [Fix AWS EC2 Systems Manager SSM Not Connected](/articles/fix-aws-ec2-systems-manager-ssm-not-connected)
- [Fix AWS EC2 Instance Not Starting](/articles/fix-aws-ec2-instance-not-starting)
- [Fix AWS EC2 Security Group Blocking](/articles/fix-aws-ec2-security-group-blocking)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS EC2 Instance Connect Not Working", "description": "Troubleshoot EC2 Instance Connect failures. Fix IAM permissions, security groups, endpoint configuration, and SSH key issues.", "url": "https://www.fixwikihub.com/fix-aws-ec2-instance-connect-not-working", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-01T05:41:45.753Z", "dateModified": "2026-04-01T05:41:45.753Z" } </script>