hashicorp/terraform · error

target_platform for provisioner has to be either

Error message

target_platform for provisioner has to be either %s or %s

What it means

Returned by parseConnectionInfo when target_platform is a non-empty value that is neither 'unix' nor 'windows'. The field controls scp command quoting and default script_path; only two platforms are implemented. An empty value is defaulted to unix, so this fires only for an explicit, unrecognized non-empty value.

Solutions

  1. Set target_platform to "unix" or "windows" (or omit it to default to unix).
  2. Remove trailing/leading whitespace from the value.
  3. Use "windows" for WinRM targets and "unix" (or omit) for SSH/Linux/BSD targets.

Example fix

// before
connection {
  host            = aws_instance.win.public_ip
  type            = "winrm"
  target_platform = "win"
}

// after
connection {
  host            = aws_instance.win.public_ip
  type            = "winrm"
  target_platform = "windows"
}
Defensive patterns

Strategy: validation

Validate before calling

# Before apply, validate target_platform is one of the allowed values:
#   grep -RnE 'target_platform\s*=\s*"(?!unix|windows)' *.tf && echo bad || echo ok
# In HCL, drive it from a variable with a validation block:
variable "target_platform" {
  type    = string
  default = "unix"
  validation {
    condition     = contains(["unix", "windows"], var.target_platform)
    error_message = "target_platform must be 'unix' or 'windows'."
  }
}

Type guard

// Go guard if constructing connection info directly:
func validTargetPlatform(p string) bool {
    return p == "" || p == "unix" || p == "windows"
}

Prevention

When it happens

Trigger: connection.target_platform set to a typo or unsupported value such as 'linux', 'macos', 'win', or 'unixx'. Any non-empty value that is not exactly 'unix' or 'windows' triggers it.

Common situations: Guessing 'linux' instead of 'unix'; using 'win' instead of 'windows'; copy-paste from non-Terraform docs; trailing whitespace in the value.

Related errors


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

Appendix: source

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

	// 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 {
		connInfo.ScriptPath = DefaultUnixScriptPath
	}
	if connInfo.ScriptPath == "" && connInfo.TargetPlatform == TargetPlatformWindows {
		connInfo.ScriptPath = DefaultWindowsScriptPath
	}
	if connInfo.Timeout != "" {
		connInfo.TimeoutVal = safeDuration(connInfo.Timeout, DefaultTimeout)
	} else {
		connInfo.TimeoutVal = DefaultTimeout
	}

	// Default all bastion config attrs to their non-bastion counterparts
	if connInfo.BastionHost != "" {
		// Format the bastion host if needed.

View on GitHub (pinned to d32a084675)