{"record":{"id":"a945ac605cfc48b2","repo":"hashicorp/terraform","slug":"host-for-provisioner-cannot-be-empty","errorCode":null,"errorMessage":"host for provisioner cannot be empty","messagePattern":"host for provisioner cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/ssh/provisioner.go","lineNumber":189,"sourceCode":"\n\t// To default Agent to true, we need to check the raw string, since the\n\t// decoded boolean can't represent \"absence of config\".\n\t//\n\t// And if SSH_AUTH_SOCK is not set, there's no agent to connect to, so we\n\t// shouldn't try.\n\tagent := v.GetAttr(\"agent\")\n\tif agent.IsNull() && os.Getenv(\"SSH_AUTH_SOCK\") != \"\" {\n\t\tconnInfo.Agent = true\n\t}\n\n\tif connInfo.User == \"\" {\n\t\tconnInfo.User = DefaultUser\n\t}\n\n\t// Check if host is empty.\n\t// Otherwise return error.\n\tif connInfo.Host == \"\" {\n\t\treturn nil, fmt.Errorf(\"host for provisioner cannot be empty\")\n\t}\n\n\t// Format the host if needed.\n\t// Needed for IPv6 support.\n\tconnInfo.Host = shared.IpFormat(connInfo.Host)\n\n\tif connInfo.Port == 0 {\n\t\tconnInfo.Port = DefaultPort\n\t}\n\t// Set default targetPlatform to unix if it's empty\n\tif connInfo.TargetPlatform == \"\" {\n\t\tconnInfo.TargetPlatform = TargetPlatformUnix\n\t} else if connInfo.TargetPlatform != TargetPlatformUnix && connInfo.TargetPlatform != TargetPlatformWindows {\n\t\treturn nil, fmt.Errorf(\"target_platform for provisioner has to be either %s or %s\", TargetPlatformUnix, TargetPlatformWindows)\n\t}\n\t// Choose an appropriate default script path based on the target platform. There is no single\n\t// suitable default script path which works on both UNIX and Windows targets.\n\tif connInfo.ScriptPath == \"\" && connInfo.TargetPlatform == TargetPlatformUnix {","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/communicator/ssh/provisioner.go#L171-L207","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Set host to a non-empty, reachable address: host = aws_instance.web.public_ip.","For private-subnet instances, set host to the private IP and add bastion_host: host = aws_instance.web.private_ip; bastion_host = ...","If using a NAT/EIP, ensure the public IP attribute is populated before the provisioner runs (depends_on).","Confirm the referenced attribute exists and is non-null (terraform console to inspect)."],"exampleFix":"// before\nconnection {\n  user        = \"ubuntu\"\n  private_key = file(\"~/.ssh/id_rsa\")\n}\n\n// after\nconnection {\n  host        = aws_instance.web.public_ip\n  user        = \"ubuntu\"\n  private_key = file(\"~/.ssh/id_rsa\")\n}","handlingStrategy":"validation","validationCode":"# Before apply, confirm the host attribute resolves to a non-empty value:\n#   terraform console\n#   > aws_instance.web.public_ip\n# Ensure the instance has a public IP, or use private_ip with a bastion.","typeGuard":null,"tryCatchPattern":"// In Go building connection info, guard host before dialing:\nif connInfo.Host == \"\" {\n    return fmt.Errorf(\"connection.host is empty; set host or bastion_host\")\n}","preventionTips":["Always set connection.host to a reachable address attribute.","For private-subnet hosts, set host to private_ip and add bastion_host.","Confirm the referenced attribute is populated (non-null) at apply time."],"tags":["terraform","connection","ssh","validation","config","provisioner"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}