hashicorp/terraform · error

registry response includes invalid version string %q: %s

Error message

registry response includes invalid version string %q: %s

What it means

In PackageMeta the registry's download response carried a protocols array whose element could not be parsed by ParseVersion (expects semver-ish). Since protocol versions gate Terraform/provider compatibility, the malformed value is fatal and the package metadata is rejected via errQueryFailed (wrapped in ErrQueryFailed).

Source

Thrown at internal/getproviders/registry_client.go:246

		SHA256SumsURL          string `json:"shasums_url"`
		SHA256SumsSignatureURL string `json:"shasums_signature_url"`

		SigningKeys SigningKeyList `json:"signing_keys"`
	}
	var body ResponseBody

	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&body); err != nil {
		return PackageMeta{}, c.errQueryFailed(provider, err)
	}

	var protoVersions VersionList
	for _, versionStr := range body.Protocols {
		v, err := ParseVersion(versionStr)
		if err != nil {
			return PackageMeta{}, c.errQueryFailed(
				provider,
				fmt.Errorf("registry response includes invalid version string %q: %s", versionStr, err),
			)
		}
		protoVersions = append(protoVersions, v)
	}
	protoVersions.Sort()

	// Verify that this version of terraform supports the providers' protocol
	// version(s)
	if len(protoVersions) > 0 {
		supportedProtos := MeetingConstraints(SupportedPluginProtocols)
		protoErr := ErrProtocolNotSupported{
			Provider: provider,
			Version:  version,
		}
		match := false
		for _, version := range protoVersions {
			if supportedProtos.Has(version) {
				match = true

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the raw registry response for the cited provider/version and confirm the protocols field contains plain numeric versions like "5.3".
  2. Report/fix the registry backend emitting the bad protocols value.
  3. Try a different provider version whose metadata is well-formed, or pin via .terraform.lock.hcl to a known-good version.
  4. If behind a mirror, check the mirror's API translation layer.

Example fix

// before (registry returns)
{"protocols":["v6"],"os":"linux",...}
// after
{"protocols":["6.0"],"os":"linux",...}
Defensive patterns

Strategy: try-catch

Type guard

// PackageMeta wraps this in ErrQueryFailed via errQueryFailed.
func isRegistryProtocolVersionErr(err error) bool {
    var qf getproviders.ErrQueryFailed
    if errors.As(err, &qf) {
        return strings.Contains(qf.Wrapped.Error(), "invalid version string")
    }
    return false
}

Try / catch

meta, err := client.PackageMeta(ctx, provider, ver, plat)
if err != nil {
    var qf getproviders.ErrQueryFailed
    if errors.As(err, &qf) && strings.Contains(qf.Wrapped.Error(), "invalid version string") {
        // registry returned a malformed protocols field; log provider/version and fall back
    }
    return err
}

Prevention

When it happens

Trigger: Calling PackageMeta against a registry whose "protocols" array for the requested provider/version contains a non-version string (e.g. "v6", "latest", "", "6.x", "grpc").

Common situations: Private/mirror registry with a bug emitting the protocol field; a proxy that rewrote the JSON; a registry API version mismatch returning a different schema; cached/stale response from a CDN.

Related errors


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