hashicorp/terraform · error · ErrQueryFailed

registry response includes invalid protocol string %q: %s

Error message

registry response includes invalid protocol string %q: %s

What it means

In findClosestProtocolCompatibleVersion (the fallback path taken when the requested provider version's protocols are unsupported), the code re-queries the registry's versions and walks each version's protocol strings through ParseVersion. If one fails to parse, it returns ErrQueryFailed wrapping this message. This blocks the helpful 'closest compatible version' suggestion.

Source

Thrown at internal/getproviders/registry_client.go:395

		v, err := ParseVersion(versionStr)
		if err != nil {
			log.Printf("[WARN] registry response includes invalid version string %q. skipping: %s", versionStr, err)
			continue
		}
		versionList = append(versionList, v)
	}
	versionList.Sort() // lowest precedence first, preserving order when equal precedence

	protoVersions := MeetingConstraints(SupportedPluginProtocols)
FindMatch:
	// put the versions in increasing order of precedence
	for index := len(versionList) - 1; index >= 0; index-- { // walk backwards to consider newer versions first
		for _, protoStr := range available[versionList[index].String()] {
			p, err := ParseVersion(protoStr)
			if err != nil {
				return UnspecifiedVersion, ErrQueryFailed{
					Provider: provider,
					Wrapped:  fmt.Errorf("registry response includes invalid protocol string %q: %s", protoStr, err),
				}
			}
			if protoVersions.Has(p) {
				match = versionList[index]
				break FindMatch
			}
		}
	}
	return match, nil
}

func (c *registryClient) addHeadersToRequest(req *http.Request) {
	if c.creds != nil {
		c.creds.PrepareRequest(req)
	}
	req.Header.Set(terraformVersionHeader, version.String())
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the registry's /versions response for the cited provider and fix any malformed protocol strings.
  2. Pin the provider to a version whose protocol Terraform supports directly (>=5,<7) to avoid the fallback path.
  3. Upgrade/patch the registry backend so protocol strings are valid semver.

Example fix

// before (versions endpoint)
{"version":"1.0","protocols":["latest"]}
// after
{"version":"1.0","protocols":["6.0"]}
Defensive patterns

Strategy: try-catch

Type guard

func isRegistryProtocolStringErr(err error) bool {
    var qf getproviders.ErrQueryFailed
    if errors.As(err, &qf) {
        return strings.Contains(qf.Wrapped.Error(), "invalid protocol string")
    }
    return false
}

Try / catch

closest, err := client.findClosestProtocolCompatibleVersion(ctx, provider, ver)
if err != nil {
    var qf getproviders.ErrQueryFailed
    if errors.As(err, &qf) && strings.Contains(qf.Wrapped.Error(), "invalid protocol string") {
        // registry versions endpoint has a malformed protocol; skip suggestion
    }
    return ver, err
}

Prevention

When it happens

Trigger: Triggered only after an initial ErrProtocolNotSupported, when the secondary ProviderVersions call yields a per-version protocols array containing a non-version string ("v6", "", "latest", "grpc").

Common situations: Registry emits inconsistent protocol strings between the versions list and the download endpoint; a version list entry with a null/empty protocols value; a private registry bug surfacing only on the version-enumeration endpoint.

Related errors


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