{"record":{"id":"b1583b6bf329d6fe","repo":"hashicorp/terraform","slug":"unsupported-protocol-version-d","errorCode":null,"errorMessage":"unsupported protocol version %d","messagePattern":"unsupported protocol version (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_providers.go","lineNumber":580,"sourceCode":"\t\traw, err := rpcClient.Dispense(tfplugin.ProviderPluginName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// store the client so that the plugin can kill the child process\n\t\tprotoVer := client.NegotiatedVersion()\n\t\tswitch protoVer {\n\t\tcase 0, 5:\n\t\t\t// As of the 0.15 release, sdk.v2 doesn't include the protocol\n\t\t\t// version in the ReattachConfig (only recently added to\n\t\t\t// go-plugin), so client.NegotiatedVersion() always returns 0. We\n\t\t\t// assume that an unmanaged provider reporting protocol version 0 is\n\t\t\t// actually using proto v5 for backwards compatibility.\n\t\t\treturn finalizeFactoryPlugin(raw, 5, provider, client), nil\n\t\tcase 6:\n\t\t\treturn finalizeFactoryPlugin(raw, 6, provider, client), nil\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported protocol version %d\", protoVer)\n\t\t}\n\t}\n}\n\n// providerFactoryError is a stub providers.Factory that returns an error\n// when called. It's used to allow providerFactories to still produce a\n// factory for each available provider in an error case, for situations\n// where the caller can do something useful with that partial result.\nfunc providerFactoryError(err error) providers.Factory {\n\treturn func() (providers.Interface, error) {\n\t\treturn nil, err\n\t}\n}\n\n// providerPluginErrors is an error implementation we can return from\n// Meta.providerFactories to capture potentially multiple errors about the\n// locally-cached plugins (or lack thereof) for particular external providers.\n//","sourceCodeStart":562,"sourceCodeEnd":598,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/command/meta_providers.go#L562-L598","documentation":"Returned by unmanagedProviderFactory after the go-plugin client negotiates a version with the reattached provider and client.NegotiatedVersion() yields a value that is not 0, 5, or 6. Unlike error 721 (which checks the configured ProtocolVersion before connecting), this fires after the live handshake, meaning the running provider process actually advertises an unsupported protocol. It indicates a real incompatibility with the process Terraform connected to.","triggerScenarios":"TF_REATTACH_PROVIDERS points at a running provider server whose go-plugin handshake reports a protocol major version outside {0,5,6}. Reached only after client.Client() and Dispense succeed, in the final switch on protoVer.","commonSituations":"The reattached process is not actually a Terraform provider (wrong PID reused); a custom/forked provider implemented an experimental protocol; the provider binary was built against a newer terraform-plugin-go that negotiated a higher version than this CLI knows.","solutions":["Verify the PID in TF_REATTACH_PROVIDERS is still the intended provider process and restart it.","Rebuild the provider against an SDK/terraform-plugin-go whose protocol version this Terraform CLI supports (5 or 6).","Use a Terraform CLI version that supports the negotiated protocol version."],"exampleFix":"// before: reattached process negotiated an unknown protocol\n// after: rebuild provider with matching SDK, e.g.\n$ go get github.com/hashicorp/terraform-plugin-go@<compatible-tag>\n$ go build && # restart the provider, re-export TF_REATTACH_PROVIDERS","handlingStrategy":"validation","validationCode":"// Sanity-check the reattached provider process is alive and is the intended binary before Terraform runs\npackage main\n\nfunc assertReattachProcessAlive(pid int, expectedBinary string) error {\n\tp, err := os.FindProcess(pid)\n\tif err != nil { return fmt.Errorf(\"reattach pid %d not found: %w\", pid, err) }\n\tif err := p.Signal(syscall.Signal(0)); err != nil {\n\t\treturn fmt.Errorf(\"reattach pid %d not running: %w\", pid, err)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restart the provider process fresh before each Terraform invocation during development.","Build the provider against an SDK whose protocol version your Terraform CLI supports.","Confirm the PID in TF_REATTACH_PROVIDERS still refers to the provider, not a recycled PID."],"tags":["provider-plugin","reattach","protocol","handshake"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}