{"record":{"id":"a7c1b3d1f477686c","repo":"opentofu/opentofu","slug":"connection-type-s-not-supported","errorCode":null,"errorMessage":"connection type '%s' not supported","messagePattern":"connection type '(.+?)' not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/communicator/communicator.go","lineNumber":76,"sourceCode":"\t}\n\n\ttypeVal := v.GetAttr(\"type\")\n\tconnType := \"\"\n\tif !typeVal.IsNull() {\n\t\tconnType = typeVal.AsString()\n\t}\n\n\tswitch connType {\n\tcase \"ssh\", \"\": // The default connection type is ssh, so if connType is empty use ssh\n\t\treturn ssh.New(v)\n\tcase \"winrm\":\n\t\t// This connection type was valid in OpenTofu v1.12 and earlier, so\n\t\t// for now we'll keep a specalized error message for it as an aid to\n\t\t// anyone who tries to use a module that was written for an older\n\t\t// version.\n\t\treturn nil, fmt.Errorf(\"'winrm' connections are not supported in OpenTofu v1.13 or later\")\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"connection type '%s' not supported\", connType)\n\t}\n}\n\n// maxBackoffDelay is the maximum delay between retry attempts\nvar maxBackoffDelay = 20 * time.Second\nvar initialBackoffDelay = time.Second\n\n// in practice we want to abort the retry asap, but for tests we need to\n// synchronize the return.\nvar retryTestWg *sync.WaitGroup\n\n// Fatal is an interface that error values can return to halt Retry\ntype Fatal interface {\n\tFatalError() error\n}\n\n// Retry retries the function f until it returns a nil error, a Fatal error, or\n// the context expires.","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/communicator/communicator.go#L58-L94","documentation":"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.","triggerScenarios":"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\").","commonSituations":"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.","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)"],"exampleFix":"# before\nconnection {\n  type = \"SSH\"\n  host = var.host\n}\n# after\nconnection {\n  type = \"ssh\"\n  host = var.host\n}","handlingStrategy":"type-guard","validationCode":"// Before apply, validate every connection block's type against supported values\nvar supportedConnTypes = map[string]bool{\"\": true, \"ssh\": true}\n\nfunc connTypeOK(t string) bool { return supportedConnTypes[t] }","typeGuard":"// Narrowing guard over raw config values (cty) for the connection type attribute\nfunc supportedConnType(v cty.Value) bool {\n  if v.IsNull() || v.Type() != cty.String {\n    return false\n  }\n  switch v.AsString() {\n  case \"\", \"ssh\":\n    return true // \"winrm\" gets its own dedicated removal error\n  default:\n    return false\n  }\n}","tryCatchPattern":"_, err := communicator.New(connVal)\nif err != nil && strings.Contains(err.Error(), \"connection type\") && strings.Contains(err.Error(), \"not supported\") {\n  // config-level mistake: fail with the offending type highlighted, do not retry\n  return fmt.Errorf(\"unsupported connection type %q: use \\\"ssh\\\" or omit type\", connType)\n}","preventionTips":["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"],"tags":["go","provisioners","connection","validation"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}