A team migrated off bastion hosts to Session Manager for a “more secure” access model, then spent an afternoon unable to connect to a single instance in a newly created private subnet. Every other instance in the account connected fine. The difference: the new subnet’s route table didn’t have a path to any of the three SSM VPC endpoints the rest of the VPC relied on, because the subnet was created after the endpoints and nobody updated the endpoint’s subnet associations. Session Manager wasn’t broken — that one subnet just had no way to reach it.
Session Manager removes the bastion host, but it doesn’t remove the network and IAM requirements underneath it — it just relocates them to different places that are less obvious when they’re missing.
The Problem
Connections fail with a handful of characteristic errors:
| Symptom | What It Means |
|---|---|
TargetNotConnected |
SSM Agent not running, not registered, or can’t reach the SSM service endpoints |
| Instance doesn’t appear in Fleet Manager | Missing or incorrect IAM instance profile, or agent not installed/outdated |
| Connects from the console but not via CLI | Local AWS CLI missing the Session Manager plugin |
| Works in one subnet, fails in another | Missing VPC endpoints (or route/security group blocking) for a private subnet with no NAT gateway |
| Session starts then immediately closes | KMS key policy blocking session encryption, or an SCP denying the API call |
Every one of these is a plumbing problem between the agent and the SSM service — not a bug in Session Manager itself.
Why Does This Happen?
- SSM Agent not installed or not running: Most current AMIs (Amazon Linux 2/2023, recent Ubuntu/Windows AMIs) ship with the agent preinstalled, but older or custom AMIs may not have it, or it may be stopped.
- Missing or misconfigured IAM instance profile: The instance needs a role with
AmazonSSMManagedInstanceCore(or equivalent least-privilege policy) attached as an instance profile — not just an IAM role that exists somewhere, but one actually attached to the instance. - No network path to SSM endpoints from a private subnet: Instances without direct internet access (no NAT gateway, no public IP) need VPC interface endpoints for
ssm,ssmmessages, andec2messages— missing any one of the three causes the agent to fail to register or fail to establish a session channel. - Security group on the VPC endpoint blocking the instance: The interface endpoint’s security group must allow inbound HTTPS (443) from the instance’s security group or subnet CIDR — a default-deny endpoint security group silently blocks all agent traffic.
- Local machine missing the Session Manager plugin:
aws ssm start-sessionfrom the CLI requires the separately installedsession-manager-pluginbinary — without it, the AWS CLI itself errors out before ever reaching AWS. - KMS key policy blocking the session encryption key: If session data encryption is enabled with a customer-managed KMS key, the caller’s IAM principal needs
kms:GenerateDataKeyandkms:Decrypton that key — a restrictive key policy causes sessions to fail immediately after starting.
The Fix
Step 1: Confirm the Instance Is Registered With SSM
aws ssm describe-instance-information \
--filters "Key=InstanceIds,Values=i-0abc123def456" \
--query "InstanceInformationList[0].{PingStatus:PingStatus,AgentVersion:PlatformType,LastPing:LastPingDateTime}"
If the instance doesn’t appear in the output at all, it has never successfully registered — that’s an agent, IAM, or network issue, not a Session Manager issue specifically.
Step 2: Verify the IAM Instance Profile
aws ec2 describe-instances \
--instance-ids i-0abc123def456 \
--query "Reservations[0].Instances[0].IamInstanceProfile"
Confirm the attached role includes the managed policy:
aws iam list-attached-role-policies \
--role-name ec2-ssm-role \
--query "AttachedPolicies[?PolicyName=='AmazonSSMManagedInstanceCore']"
If missing, attach it:
aws iam attach-role-policy \
--role-name ec2-ssm-role \
--policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Step 3: Check Agent Status on the Instance
If you have any other access path (console-based EC2 Instance Connect, or the instance is reachable), check directly:
sudo systemctl status amazon-ssm-agent
sudo systemctl restart amazon-ssm-agent
Step 4: Verify Required VPC Endpoints Exist and Are Reachable From the Subnet
aws ec2 describe-vpc-endpoints \
--filters "Name=vpc-id,Values=vpc-0abc123def" \
--query "VpcEndpoints[*].{Service:ServiceName,State:State,Subnets:SubnetIds}" \
--output table
Confirm all three are present: com.amazonaws.us-east-1.ssm, com.amazonaws.us-east-1.ssmmessages, com.amazonaws.us-east-1.ec2messages. If the affected subnet isn’t in the endpoint’s subnet list, add it:
aws ec2 modify-vpc-endpoint \
--vpc-endpoint-id vpce-0abc123def \
--add-subnet-ids subnet-0newsubnet456
Step 5: Check the VPC Endpoint’s Security Group
aws ec2 describe-security-groups \
--group-ids sg-0endpointsg123 \
--query "SecurityGroups[0].IpPermissions"
Should allow inbound 443 from the instance’s security group or subnet CIDR:
aws ec2 authorize-security-group-ingress \
--group-id sg-0endpointsg123 \
--protocol tcp \
--port 443 \
--source-group sg-0instancesg456
Step 6: Install the Session Manager Plugin Locally
aws ssm start-session --target i-0abc123def456
If this fails with a plugin-not-found error, install it (macOS example):
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
unzip sessionmanager-bundle.zip
sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin
Step 7: Check KMS Key Permissions if Session Encryption Is Enabled
aws ssm get-document \
--name SSM-SessionManagerRunShell \
--query "Content" | python3 -m json.tool | grep -i kms
Verify the caller’s role has permission on the referenced key:
aws kms get-key-policy \
--key-id arn:aws:kms:us-east-1:111122223333:key/abc-123 \
--policy-name default
Is This Safe?
The describe and get commands are read-only. Attaching the AmazonSSMManagedInstanceCore policy is additive and low-risk. Modifying a VPC endpoint’s subnet associations and security group rules affects all traffic using that endpoint — review what else depends on it before changing its security group broadly, though adding subnet associations is generally safe and non-disruptive to existing connections.
Key Takeaway
Session Manager failures are network and IAM plumbing issues wearing a connectivity error message. Work through it in order: confirm the instance registers with SSM at all, confirm the instance profile has the right managed policy, confirm the three required VPC endpoints exist and are reachable from the specific subnet in question, and confirm the local machine has the plugin installed. Private subnets added after the original VPC endpoint setup are the single most common gap — endpoints don’t retroactively cover new subnets unless you explicitly associate them.
Have questions or ran into a different Systems Manager issue? Connect with me on LinkedIn or X.