hashicorp/terraform · error

no supported plugins for protocol %d

Error message

no supported plugins for protocol %d

What it means

Raised inside unmanagedProviderFactory when reattach.ProtocolVersion (from TF_REATTACH_PROVIDERS) does not correspond to any key in tfplugin.VersionedPlugins, which only registers protocol versions 5 and 6. Unmanaged providers are externally-started provider servers used during SDK/provider development testing; Terraform connects to them instead of launching its own plugin process. An unknown protocol number means the provider under test speaks a version Terraform does not support.

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 c9def3e214)

Solutions

  1. Confirm the provider under test is built with SDK that speaks protocol 5 or 6 and set protocol_version accordingly in TF_REATTACH_PROVIDERS.
  2. Upgrade or downgrade Terraform CLI to match the protocol version the provider SDK targets.
  3. Remove TF_REATTACH_PROVIDERS from the environment if you are not actively developing a provider.

Example fix

// before
$ export TF_REATTACH_PROVIDERS='{"registry.terraform.io/hashicorp/example":{"protocol":"grpc","protocol_version":7,"pid":12345}}'
// after (use a supported protocol version)
$ export TF_REATTACH_PROVIDERS='{"registry.terraform.io/hashicorp/example":{"protocol":"grpc","protocol_version":6,"pid":12345}}'
Defensive patterns

Strategy: validation

Validate before calling

// Validate TF_REATTACH_PROVIDERS only references supported protocol versions before invoking Terraform
package main

import (
	"encoding/json"
	"os"
)

func validateReattachProtocols(raw string) error {
	if raw == "" { return nil }
	var cfg map[string]struct{ ProtocolVersion int `json:"protocol_version"` }
	if err := json.Unmarshal([]byte(raw), &cfg); err != nil { return err }
	for name, p := range cfg {
		if p.ProtocolVersion != 5 && p.ProtocolVersion != 6 {
			return fmt.Errorf("provider %s: protocol_version must be 5 or 6, got %d", name, p.ProtocolVersion)
		}
	}
	return nil
}

Prevention

When it happens

Trigger: Set TF_REATTACH_PROVIDERS with a ProtocolVersion other than 5 or 6 (e.g. a future v7 or a malformed config), then run any Terraform command that loads providers. Also reachable when the reattach JSON omits/hand-types the protocol_version field to an unexpected integer.

Common situations: Provider developer is testing against a bleeding-edge SDK that bumped the protocol; the reattach config JSON was copy-pasted with a stale/wrong protocol_version; mismatch between the Terraform CLI version and the SDK protocol version the provider was compiled with.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/9d214d2616372d04. Report an issue: GitHub.