Packer Error: 'Timeout waiting for SSH.' — Cause, Fix, and Troubleshooting Guide
Fix Packer 'Timeout waiting for SSH.' — diagnose security groups, ssh_username, key pairs, communicator, and missing public IP on the build instance.
- #iac
- #infrastructure-as-code
- #packer
- #troubleshooting
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Packer launches a temporary build instance, then blocks until it can open an SSH (or WinRM) session to run your provisioners. If it cannot connect within ssh_timeout, it tears the instance down and reports:
==> amazon-ebs.ubuntu: Waiting for SSH to become available...
==> amazon-ebs.ubuntu: Timeout waiting for SSH.
Build 'amazon-ebs.ubuntu' errored after 5 minutes 2 seconds:
Timeout waiting for SSH.
This is almost always a network-path or credentials problem, not a Packer bug. The instance booted, but Packer’s connection was refused, filtered, or authenticated with the wrong user/key. The build instance is deleted on failure, which makes it feel opaque — the trick is to keep the instance alive and inspect the path.
Symptoms
- Build reaches “Waiting for SSH to become available…” then stalls for the full timeout.
- Error
Timeout waiting for SSH.afterssh_timeoutelapses. PACKER_LOG=1shows repeatedhandshakeorconnection refused/i/o timeoutlines.- Works in one subnet/VPC but not another.
- WinRM variant:
Timeout waiting for WinRM.
Common Root Causes
1. Security group does not allow inbound SSH from Packer’s IP
The temporary SG (or the one you specified) must allow TCP 22 from wherever Packer runs.
# Let Packer create and manage a temporary SG (recommended)
temporary_security_group_source_cidrs = ["203.0.113.10/32"]
# or open to your build network
If a restrictive security_group_id is pinned with no port 22 ingress, every handshake times out.
2. Instance has no public IP and Packer connects over the public interface
In a public subnet you need associate_public_ip_address = true; in a private subnet Packer must reach the instance via its private IP (a bastion, ssh_interface = "private_ip", or Session Manager).
associate_public_ip_address = true
ssh_interface = "public_ip"
3. Wrong ssh_username for the base AMI
Each distro AMI ships a different default user. Using ec2-user on an Ubuntu AMI fails authentication and looks like a timeout.
Ubuntu -> ubuntu
Amazon Linux -> ec2-user
Debian -> admin
RHEL -> ec2-user or cloud-user
4. Key pair / communicator mismatch
If you pin an ssh_keypair_name but do not supply the matching ssh_private_key_file, Packer cannot authenticate. Leaving both blank lets Packer generate a temporary key pair, which is usually what you want.
5. Subnet routing / NACL blocks the return path
A private subnet with no NAT, a NACL that drops ephemeral return ports, or a missing route to an internet/transit gateway all break the SSH path even when the SG is correct.
6. Instance still booting or cloud-init not finished
Very slow user-data or a broken cloud-init can leave sshd not yet listening when the timeout is short.
How to Diagnose
Keep the instance alive to inspect it
PACKER_LOG=1 packer build -debug template.pkr.hcl
-debug pauses between steps and prints the instance IP and key path so you can try SSH by hand while the instance is still running.
Try the connection manually
ssh -vvv -i /path/to/temp_key.pem ubuntu@203.0.113.55
connection refused = sshd/routing; permission denied = wrong user or key; hang = SG/NACL/routing.
Confirm the network path
aws ec2 describe-security-groups --group-ids sg-0abc123 \
--query 'SecurityGroups[].IpPermissions'
aws ec2 describe-instances --instance-ids i-0abc123 \
--query 'Reservations[].Instances[].{Pub:PublicIpAddress,Subnet:SubnetId}'
Bump the timeout to rule out slow boot
ssh_timeout = "10m"
Fixes
Open SSH and give the instance a reachable address
source "amazon-ebs" "ubuntu" {
region = var.region
instance_type = "t3.micro"
ssh_username = "ubuntu"
associate_public_ip_address = true
ssh_interface = "public_ip"
# Packer auto-manages a temp SG allowing 22 from your IP:
temporary_security_group_source_cidrs = ["203.0.113.10/32"]
}
Use the correct username per AMI
ssh_username = "ec2-user" # Amazon Linux; use "ubuntu" for Ubuntu AMIs
Build in private subnets via Session Manager (no inbound 22)
ssh_interface = "session_manager"
iam_instance_profile = "packer-ssm-profile"
communicator = "ssh"
This removes the need for any inbound SSH rule or public IP.
Let Packer manage the key pair
Remove ssh_keypair_name/ssh_private_key_file and let Packer generate an ephemeral key so the public/private halves always match.
What to Watch Out For
- Prefer Packer’s temporary security group and temporary key pair over pinned ones — fewer moving parts to misalign.
- Match
ssh_usernameto the exact base AMI; this is the single most common cause. - In private subnets, standardize on Session Manager so you never expose port 22.
- Set
ssh_timeoutgenerously (5–10m) for AMIs with heavy cloud-init. - Test the SG/NACL/route path with
-debugbefore blaming Packer.
Related Guides
- Packer amazon-ebs Build Errored
- Packer Failed to Prepare Build
- Managing Secrets in Infrastructure as Code
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.