hashicorp/terraform · error
no supported plugins for protocol
Error message
no supported plugins for protocol %d
What it means
In unmanagedProviderFactory, when a ReattachConfig supplies a non-zero ProtocolVersion, Terraform looks it up in tfplugin.VersionedPlugins. If that protocol version is absent from the built-in plugin set, the factory returns this error. It also covers the zero case when tfplugin.VersionedPlugins[5] is itself missing. This path is only used for debugging via TF_REATTACH_PROVIDERS.
Solutions
- Set ProtocolVersion to 5 (terraform-plugin-sdk v2) or 6 (terraform-plugin-framework) in the reattach config.
- Regenerate the reattach JSON by running the provider with the Terraform-provided harness rather than authoring it by hand.
- Confirm the Terraform/OpenTofu build actually registers tfplugin.VersionedPlugins[5] and [6].
- Stop using TF_REATTACH_PROVIDERS for production runs; it is a development-only escape hatch.
Example fix
// before: { "registry.terraform.io/hashicorp/example": { "ProtocolVersion": 4, ... } }
// after
{ "registry.terraform.io/hashicorp/example": { "ProtocolVersion": 6, "Pid": 12345, "Test": true, "Addr": { "Network": "unix", "String": "/tmp/plugin" } } } Defensive patterns
Strategy: validation
Validate before calling
// Validate the reattach protocol before passing it to Terraform.
func validReattachProto(v int) bool { return v == 0 || v == 5 || v == 6 } Type guard
func isSupportedProtocol(v int) bool {
_, ok := tfplugin.VersionedPlugins[v]
return ok || v == 0
} Prevention
- Generate TF_REATTACH_PROVIDERS JSON from the provider dev harness, not by hand.
- Keep ProtocolVersion at 6 for terraform-plugin-framework providers.
- Only use reattach during active provider development.
When it happens
Trigger: TF_REATTACH_PROVIDERS is set to a JSON reattach config whose ProtocolVersion is a value not present in tfplugin.VersionedPlugins (currently only 5 and 6 are registered), or ProtocolVersion is 0 and the default proto-5 plugin table is unavailable in this build.
Common situations: Provider developer sets TF_REATTACH_PROVIDERS with a hand-written config naming protocol 4 or 7; sdk.v2 provider whose ReattachConfig omits the version but running a stripped build without the v5 plugin table; mismatch between the provider under development and the Terraform build's supported protocols.
Related errors
- unsupported protocol version
- error when obtaining provider instance during state store…
- action schema not found for action
- error loading plugin path
- error loading plugin path
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/9d214d2616372d04.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/meta_providers.go:551
Managed: false,
Reattach: reattach,
SyncStdout: logging.PluginOutputMonitor(fmt.Sprintf("%s:stdout", provider)),
SyncStderr: logging.PluginOutputMonitor(fmt.Sprintf("%s:stderr", provider)),
}
if reattach.ProtocolVersion == 0 {
// As of the 0.15 release, sdk.v2 doesn't include the protocol
// version in the ReattachConfig (only recently added to
// go-plugin), so client.NegotiatedVersion() always returns 0. We
// assume that an unmanaged provider reporting protocol version 0 is
// actually using proto v5 for backwards compatibility.
if defaultPlugins, ok := tfplugin.VersionedPlugins[5]; ok {
config.Plugins = defaultPlugins
} else {
return nil, errors.New("no supported plugins for protocol 0")
}
} else if plugins, ok := tfplugin.VersionedPlugins[reattach.ProtocolVersion]; !ok {
return nil, fmt.Errorf("no supported plugins for protocol %d", reattach.ProtocolVersion)
} else {
config.Plugins = plugins
}
client := plugin.NewClient(config)
rpcClient, err := client.Client()
if err != nil {
return nil, err
}
raw, err := rpcClient.Dispense(tfplugin.ProviderPluginName)
if err != nil {
return nil, err
}
// store the client so that the plugin can kill the child process
protoVer := client.NegotiatedVersion()
switch protoVer {View on GitHub (pinned to d32a084675)