opentofu/opentofu · error
connection type '%s' not supported
Error message
connection type '%s' not supported
What it means
Returned by communicator.New for any connection type other than "ssh", "" (empty, meaning the SSH default), or "winrm" (which gets its own removal-specific error). The string in the message is whatever the connection block's 'type' attribute evaluated to.
Source
Thrown at internal/communicator/communicator.go:76
}
typeVal := v.GetAttr("type")
connType := ""
if !typeVal.IsNull() {
connType = typeVal.AsString()
}
switch connType {
case "ssh", "": // The default connection type is ssh, so if connType is empty use ssh
return ssh.New(v)
case "winrm":
// This connection type was valid in OpenTofu v1.12 and earlier, so
// for now we'll keep a specalized error message for it as an aid to
// anyone who tries to use a module that was written for an older
// version.
return nil, fmt.Errorf("'winrm' connections are not supported in OpenTofu v1.13 or later")
default:
return nil, fmt.Errorf("connection type '%s' not supported", connType)
}
}
// maxBackoffDelay is the maximum delay between retry attempts
var maxBackoffDelay = 20 * time.Second
var initialBackoffDelay = time.Second
// in practice we want to abort the retry asap, but for tests we need to
// synchronize the return.
var retryTestWg *sync.WaitGroup
// Fatal is an interface that error values can return to halt Retry
type Fatal interface {
FatalError() error
}
// Retry retries the function f until it returns a nil error, a Fatal error, or
// the context expires.View on GitHub (pinned to 3561785c48)
Solutions
- Set type = "ssh" or remove the type attribute entirely (ssh is the default)
- Check spelling and case of the type value; run 'tofu validate' to catch it before apply
- If the type comes from a variable, print/verify its value (tofu console or null_resource triggers)
Example fix
# before
connection {
type = "SSH"
host = var.host
}
# after
connection {
type = "ssh"
host = var.host
} Defensive patterns
Strategy: type-guard
Validate before calling
// Before apply, validate every connection block's type against supported values
var supportedConnTypes = map[string]bool{"": true, "ssh": true}
func connTypeOK(t string) bool { return supportedConnTypes[t] } Type guard
// Narrowing guard over raw config values (cty) for the connection type attribute
func supportedConnType(v cty.Value) bool {
if v.IsNull() || v.Type() != cty.String {
return false
}
switch v.AsString() {
case "", "ssh":
return true // "winrm" gets its own dedicated removal error
default:
return false
}
} Try / catch
_, err := communicator.New(connVal)
if err != nil && strings.Contains(err.Error(), "connection type") && strings.Contains(err.Error(), "not supported") {
// config-level mistake: fail with the offending type highlighted, do not retry
return fmt.Errorf("unsupported connection type %q: use \"ssh\" or omit type", connType)
} Prevention
- Always run tofu validate before apply - connection types are checked there
- Omit 'type' entirely to get the ssh default, eliminating typo risk
- Keep connection types lowercase; document the two valid values in module READMEs
When it happens
Trigger: A provisioner connection block with type set to a typo or unsupported value: "sshh", "SSH" (capitalized), "sftp", "rdp", or a variable that interpolates to something unexpected (including a null/unknown value passed as string "null").
Common situations: Typos in copied connection blocks; case sensitivity surprises ("SSH" is not accepted); using a type valid in other tools (e.g. Paramiko strings) that OpenTofu never supported; ternary expressions in type that yield a wrong branch.
Related errors
- state name not allow to be empty
- the string provided in credentials is neither valid json nor
- Error decoding encryption key: %w
- %q is not a valid state name
- 'winrm' connections are not supported in OpenTofu v1.13 or l
AI-assisted analysis of opentofu/opentofu@3561785c48 (2026-08-15).
Data as JSON: /api/errors/a7c1b3d1f477686c.
Report an issue: GitHub.