hashicorp/terraform · error

host for provisioner cannot be empty

Error message

host for provisioner cannot be empty

What it means

Returned by parseConnectionInfo when connInfo.Host is empty after decoding and defaults are applied. The host is the connection target IP/DNS name; without it the provisioner cannot dial anything. There is no default host (unlike user, which defaults to DefaultUser), so an empty host is always an error.

Solutions

  1. Set host to a non-empty, reachable address: host = aws_instance.web.public_ip.
  2. For private-subnet instances, set host to the private IP and add bastion_host: host = aws_instance.web.private_ip; bastion_host = ...
  3. If using a NAT/EIP, ensure the public IP attribute is populated before the provisioner runs (depends_on).
  4. Confirm the referenced attribute exists and is non-null (terraform console to inspect).

Example fix

// before
connection {
  user        = "ubuntu"
  private_key = file("~/.ssh/id_rsa")
}

// after
connection {
  host        = aws_instance.web.public_ip
  user        = "ubuntu"
  private_key = file("~/.ssh/id_rsa")
}
Defensive patterns

Strategy: validation

Validate before calling

# Before apply, confirm the host attribute resolves to a non-empty value:
#   terraform console
#   > aws_instance.web.public_ip
# Ensure the instance has a public IP, or use private_ip with a bastion.

Try / catch

// In Go building connection info, guard host before dialing:
if connInfo.Host == "" {
    return fmt.Errorf("connection.host is empty; set host or bastion_host")
}

Prevention

When it happens

Trigger: connection block with no host attribute, host = "", or host = an attribute that evaluated to null/empty (e.g. aws_instance.web.public_ip when the instance has no public IP, or referencing the wrong field). Also when the resource is private-subnet-only and no bastion/bastion_host is set.

Common situations: Forgetting the host attribute; referencing public_ip on an instance in a private subnet with no public IP; using a computed attribute that is null at plan time; referencing the wrong resource attribute (e.g. id instead of public_ip).

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/a945ac605cfc48b2. Report an issue: GitHub.

Appendix: source

Thrown at internal/communicator/ssh/provisioner.go:189

	// To default Agent to true, we need to check the raw string, since the
	// decoded boolean can't represent "absence of config".
	//
	// And if SSH_AUTH_SOCK is not set, there's no agent to connect to, so we
	// shouldn't try.
	agent := v.GetAttr("agent")
	if agent.IsNull() && os.Getenv("SSH_AUTH_SOCK") != "" {
		connInfo.Agent = true
	}

	if connInfo.User == "" {
		connInfo.User = DefaultUser
	}

	// Check if host is empty.
	// Otherwise return error.
	if connInfo.Host == "" {
		return nil, fmt.Errorf("host for provisioner cannot be empty")
	}

	// Format the host if needed.
	// Needed for IPv6 support.
	connInfo.Host = shared.IpFormat(connInfo.Host)

	if connInfo.Port == 0 {
		connInfo.Port = DefaultPort
	}
	// Set default targetPlatform to unix if it's empty
	if connInfo.TargetPlatform == "" {
		connInfo.TargetPlatform = TargetPlatformUnix
	} else if connInfo.TargetPlatform != TargetPlatformUnix && connInfo.TargetPlatform != TargetPlatformWindows {
		return nil, fmt.Errorf("target_platform for provisioner has to be either %s or %s", TargetPlatformUnix, TargetPlatformWindows)
	}
	// Choose an appropriate default script path based on the target platform. There is no single
	// suitable default script path which works on both UNIX and Windows targets.
	if connInfo.ScriptPath == "" && connInfo.TargetPlatform == TargetPlatformUnix {

View on GitHub (pinned to d32a084675)