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

  1. Set ProtocolVersion to 5 (terraform-plugin-sdk v2) or 6 (terraform-plugin-framework) in the reattach config.
  2. Regenerate the reattach JSON by running the provider with the Terraform-provided harness rather than authoring it by hand.
  3. Confirm the Terraform/OpenTofu build actually registers tfplugin.VersionedPlugins[5] and [6].
  4. 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

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


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)