This error occurs when Terraform's SSH client cannot authenticate with a remote server during provisioner operations. It typically indicates missing or misconfigured authentication credentials (private key, password, or SSH agent).
When Terraform attempts to connect to a remote host using SSH provisioners (remote-exec, file, etc.), it uses a built-in SSH client. This error appears when the SSH handshake completes but authentication fails because Terraform cannot present valid credentials to the server. The server rejects the connection because no supported authentication methods remainโeither the credentials weren't provided, were in an unsupported format, or don't match what's configured on the remote host.
Test if you can connect to the remote host using standard SSH command:
ssh -i /path/to/private/key -u [email protected]If manual SSH succeeds but Terraform fails, the issue is with Terraform's SSH configuration, not the connection itself. If manual SSH also fails, verify the key and host are correct before proceeding.
Add a proper connection block to your Terraform provisioner. Use the file() function to read the actual key contents, not just the key name:
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
key_name = "my-key"
provisioner "remote-exec" {
inline = ["echo Connected!"]
connection {
type = "ssh"
user = "ec2-user" # Use correct user for your AMI
private_key = file("~/.ssh/my-key.pem")
host = self.public_ip
timeout = "5m"
}
}
}The critical parts:
- Use file("path/to/key") not just the key name
- Specify correct user for your OS (ec2-user, ubuntu, centos, admin, etc.)
- Use host = the actual IP or hostname
If your private key is password-protected, Terraform cannot use it directly. Instead, use the SSH agent:
connection {
type = "ssh"
user = "ubuntu"
agent = true # Use SSH agent for key authentication
host = self.public_ip
}Before running Terraform, ensure your key is loaded:
ssh-add ~/.ssh/my-key.pemThis prompts for the passphrase once, then SSH agent handles authentication.
Some cloud providers have delays before SSH is fully ready. Increase the timeout:
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/key.pem")
host = self.public_ip
timeout = "10m" # Increased from default
}If the remote instance takes time to configure authorized_keys, you can also add a small delay:
provisioner "remote-exec" {
inline = ["echo Connected!"]
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/key.pem")
host = self.public_ip
}
depends_on = [aws_instance.example]
}SSH requires private keys to have restrictive permissions (600). Check your key:
ls -l ~/.ssh/my-key.pemShould show: -rw------- 1 user group (600 permissions)
Fix if needed:
chmod 600 ~/.ssh/my-key.pemAlso verify the key format is correct (should start with -----BEGIN RSA PRIVATE KEY----- or -----BEGIN EC PRIVATE KEY-----).
If agent-based authentication has issues, try explicitly disabling it:
connection {
type = "ssh"
user = "ubuntu"
private_key = file("~/.ssh/key.pem")
host = self.public_ip
agent = false # Force key-based auth without agent
timeout = "5m"
}This forces Terraform to use the private_key file directly instead of delegating to SSH agent.
Advanced troubleshooting:
Amazon Linux 2023 Compatibility: Terraform 0.14.x has known issues authenticating with Amazon Linux 2023 (OpenSSH 8.7+). Upgrade to Terraform 1.0+ or use Amazon Linux 2 instead.
CoreOS/Fedora Issues: Some Linux distributions have SSH daemon behavior differences. If you can't connect with standard key auth, check if the distribution uses non-standard SSH configuration or SELinux policies that might block authentication.
Provider-specific SSH URIs: If using terraform-provider-libvirt or connecting via SSH URI (rather than standard provisioners), the SSH client path differs. Verify your provider's documentation for its specific connection requirements.
Debugging with TF_LOG: Set TF_LOG=DEBUG environment variable when running terraform apply to see detailed SSH negotiation logs, which can reveal exactly where authentication fails.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform