hashicorp/terraform · error

no supported plugins for protocol 0

Error message

no supported plugins for protocol 0

What it means

Returned while building a provider client for a **development reattach** configuration (`-reattach`/`TF_REATTACH_PROVIDERS`) when the reattach config reports protocol version 0 AND the build's `tfplugin.VersionedPlugins` map has no entry for version 5. Normally Terraform assumes an unmanaged v0 protocol is really proto v5, but this build lacks the v5 plugin set, so it cannot serve the provider.

Solutions

  1. Use a current official Terraform release whose `VersionedPlugins` includes v5 when reattaching to SDK v2 providers.
  2. Ensure the provider's ReattachConfig sets `ProtocolVersion` (5 or 6) instead of leaving it 0.
  3. Rebuild/re-install the provider via `go install` so the reattach info reflects the negotiated protocol.
Defensive patterns

Strategy: validation

Validate before calling

// When building a reattach client, validate the protocol map up front:
if reattach.ProtocolVersion == 0 {
    if _, ok := tfplugin.VersionedPlugins[5]; !ok {
        return nil, fmt.Errorf("this build has no v5 plugins; cannot reattach to SDK v2 provider %q", reattach.PluginName)
    }
}

Type guard

// hasProto5 reports whether the running binary can serve a v5 provider.
func hasProto5() bool {
    _, ok := tfplugin.VersionedPlugins[5]
    return ok
}

Prevention

When it happens

Trigger: `config.Plugins` lookup falls into the `reattach.ProtocolVersion == 0` branch and `tfplugin.VersionedPlugins[5]` is absent (ok == false) in this compiled Terraform binary.

Common situations: Using an outdated or custom-built Terraform binary to reattach to an SDK v2 provider whose ReattachConfig omits the negotiated version; mixing a very old `tfplugin` dependency set with a newer provider dev workflow.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/51e018bec79beeba. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/meta_providers.go:548

			HandshakeConfig:  tfplugin.Handshake,
			Logger:           logging.NewProviderLogger("unmanaged."),
			AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
			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
		}

View on GitHub (pinned to d32a084675)