This networking error occurs when Terraform cannot establish a connection to a cloud provider, registry, or remote resource. It typically indicates DNS resolution failures, network connectivity issues, or security group/firewall restrictions blocking the required ports.
The "dial tcp: i/o timeout" error is a Go networking error that means Terraform tried to connect to a network address but the connection attempt timed out without receiving a response. This can happen during several Terraform operations: 1. **Provider initialization**: Terraform cannot reach the cloud provider's API endpoints 2. **Registry communication**: Cannot download providers from registry.terraform.io 3. **Remote provisioners**: SSH connections fail when using file or remote-exec provisioners 4. **Kubernetes/Cluster operations**: Cannot establish connections to cluster APIs The "dial tcp" part specifically refers to establishing a TCP connection, and "i/o timeout" means the operation didn't complete within the timeout window.
First, test basic network connectivity to the endpoint. Replace the IP and port with your actual endpoint:
# Test with curl (for HTTP/HTTPS endpoints)
curl -v https://api.example.com:443
# Test with nc (netcat) for TCP connectivity
nc -zv 54.89.109.252 22
# Test with timeout to prevent hanging
timeout 5 bash -c '</dev/tcp/54.89.109.252/22' && echo "Connected" || echo "Connection failed"If these commands fail, it confirms network connectivity is blocked. If they succeed, the issue may be specific to Terraform or the provider.
Ensure your security groups and firewall rules allow outbound traffic to the required endpoints:
For AWS security groups:
- Add outbound rules allowing HTTPS (443) to cloud provider API endpoints
- If using SSH provisioners, allow SSH (22) to your instance IP
For Azure Network Security Groups:
- Create outbound rules allowing HTTPS (443) and SSH (22) as needed
- Verify no deny rules are blocking required traffic
For GCP firewall rules:
- Create egress rules allowing traffic to required endpoints
- Ensure rules have correct priorities and don't conflict
Example AWS CLI command:
aws ec2 authorize-security-group-egress \
--group-id sg-12345678 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0If your network uses an HTTP/HTTPS proxy, configure Terraform to use it:
# Set environment variables before running Terraform
export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1,internal.example.com
# Or in PowerShell on Windows
$env:HTTP_PROXY = "http://proxy.example.com:8080"
$env:HTTPS_PROXY = "http://proxy.example.com:8080"
# Then run Terraform
terraform planYou can also add these to your shell profile to make them persistent:
echo 'export HTTPS_PROXY=http://proxy.example.com:8080' >> ~/.bashrc
source ~/.bashrcIf you're getting timeouts on DNS lookups, test DNS resolution:
# Test DNS resolution
nslookup api.example.com
dig api.example.com
# Or use getent on Linux
getent hosts api.example.com
# Test with different DNS server
nslookup api.example.com 8.8.8.8If DNS lookups fail:
- Check /etc/resolv.conf on Linux to verify nameserver configuration
- On Windows, run ipconfig /all to see DNS servers
- Try using a public DNS server (8.8.8.8) for testing
- Contact your network administrator if DNS is misconfigured
For cloud provisioners, verify your VPC has proper routing:
For AWS EC2 instances in a VPC:
- Instance must be in a subnet with a route to an Internet Gateway (IGW)
- Check route table: destination 0.0.0.0/0 should point to the IGW
Check routing in AWS console:
- Go to EC2 > Instances > Your Instance > Subnet
- Check Route Table > verify routes include IGW
For on-premises or private networks:
- Ensure instance has connectivity to your Terraform control machine
- If using jumphosts/bastion hosts, configure SSH ProxyCommand
Example for SSH through bastion:
# In ~/.ssh/config
Host private-instance
HostName 10.0.0.5
ProxyCommand ssh -W %h:%p bastion-host
User ec2-userIf connectivity works but operations are slow, increase Terraform timeouts:
# For remote-exec provisioner
resource "aws_instance" "example" {
# ... other configuration ...
provisioner "remote-exec" {
inline = ["echo 'Hello'"]
connection {
type = "ssh"
user = "ec2-user"
private_key = file("~/.ssh/id_rsa")
host = self.public_ip
timeout = "5m" # Increase from default 5m
}
}
}
# For resource timeouts
resource "aws_instance" "example" {
# ... other configuration ...
timeouts {
create = "10m"
delete = "10m"
}
}Provider-specific timeout examples:
# Kubernetes provider
provider "kubernetes" {
host = aws_eks_cluster.example.endpoint
token = data.aws_eks_cluster_auth.example.token
# Add connection settings
insecure = false
load_config_file = false
}
# AWS provider
provider "aws" {
region = "us-east-1"
# Some operations may benefit from retry configuration
}Enable verbose logging to see exactly where Terraform is trying to connect:
# Enable Terraform debug logging
export TF_LOG=DEBUG
export TF_LOG_PATH=terraform.log
terraform plan 2>&1 | tee terraform.log
# Search for network-related errors
grep -i "dial|timeout|connection" terraform.log
# For AWS provider debugging
export AWS_DEBUG=true
# For Kubernetes provider debugging
export KUBERNETES_DEBUG=trueDebug logs will show:
- The exact IP address and port being connected to
- DNS lookup details
- Which provider/component is timing out
- Connection attempt duration before timeout
IPv6 Issues on macOS: If you're experiencing slow Terraform runs or timeouts on macOS, check System Settings > Network and disable IPv6. Some networks have issues with IPv6 that can cause significant slowdowns. The HashiCorp Terraform team has been tracking this issue (https://github.com/hashicorp/terraform/issues/31467).
Intermittent Timeouts: If timeouts occur sporadically (not consistently), this suggests a reliability issue rather than a complete network blockage. This could be:
- Unstable network connection quality
- Rate limiting on the remote endpoint (temporary rejection)
- Load balancer or proxy dropping connections randomly
Try running the same command multiple times to see if it eventually succeeds.
Kubernetes Provider Specifics: When using the Kubernetes provider and getting "dial tcp: i/o timeout", ensure:
- The cluster is running and the API server is accessible
- Security groups allow egress to the Kubernetes API port (usually 443)
- If using kubeconfig, verify the server endpoint in the kubeconfig file is correct
- For EKS, ensure the security group allows inbound access to port 443
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