{"record":{"id":"2d151a9934bbefa2","repo":"hashicorp/terraform","slug":"registry-response-includes-invalid-version-string","errorCode":null,"errorMessage":"registry response includes invalid version string %q: %s","messagePattern":"registry response includes invalid version string %q: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":246,"sourceCode":"\t\tSHA256SumsURL          string `json:\"shasums_url\"`\n\t\tSHA256SumsSignatureURL string `json:\"shasums_signature_url\"`\n\n\t\tSigningKeys SigningKeyList `json:\"signing_keys\"`\n\t}\n\tvar body ResponseBody\n\n\tdec := json.NewDecoder(resp.Body)\n\tif err := dec.Decode(&body); err != nil {\n\t\treturn PackageMeta{}, c.errQueryFailed(provider, err)\n\t}\n\n\tvar protoVersions VersionList\n\tfor _, versionStr := range body.Protocols {\n\t\tv, err := ParseVersion(versionStr)\n\t\tif err != nil {\n\t\t\treturn PackageMeta{}, c.errQueryFailed(\n\t\t\t\tprovider,\n\t\t\t\tfmt.Errorf(\"registry response includes invalid version string %q: %s\", versionStr, err),\n\t\t\t)\n\t\t}\n\t\tprotoVersions = append(protoVersions, v)\n\t}\n\tprotoVersions.Sort()\n\n\t// Verify that this version of terraform supports the providers' protocol\n\t// version(s)\n\tif len(protoVersions) > 0 {\n\t\tsupportedProtos := MeetingConstraints(SupportedPluginProtocols)\n\t\tprotoErr := ErrProtocolNotSupported{\n\t\t\tProvider: provider,\n\t\t\tVersion:  version,\n\t\t}\n\t\tmatch := false\n\t\tfor _, version := range protoVersions {\n\t\t\tif supportedProtos.Has(version) {\n\t\t\t\tmatch = true","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/registry_client.go#L228-L264","documentation":"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).","triggerScenarios":"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\").","commonSituations":"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.","solutions":["Inspect the raw registry response for the cited provider/version and confirm the protocols field contains plain numeric versions like \"5.3\".","Report/fix the registry backend emitting the bad protocols value.","Try a different provider version whose metadata is well-formed, or pin via .terraform.lock.hcl to a known-good version.","If behind a mirror, check the mirror's API translation layer."],"exampleFix":"// before (registry returns)\n{\"protocols\":[\"v6\"],\"os\":\"linux\",...}\n// after\n{\"protocols\":[\"6.0\"],\"os\":\"linux\",...}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"// PackageMeta wraps this in ErrQueryFailed via errQueryFailed.\nfunc isRegistryProtocolVersionErr(err error) bool {\n    var qf getproviders.ErrQueryFailed\n    if errors.As(err, &qf) {\n        return strings.Contains(qf.Wrapped.Error(), \"invalid version string\")\n    }\n    return false\n}","tryCatchPattern":"meta, err := client.PackageMeta(ctx, provider, ver, plat)\nif err != nil {\n    var qf getproviders.ErrQueryFailed\n    if errors.As(err, &qf) && strings.Contains(qf.Wrapped.Error(), \"invalid version string\") {\n        // registry returned a malformed protocols field; log provider/version and fall back\n    }\n    return err\n}","preventionTips":["Use the official public registry where protocol strings are validated.","For a private registry, add an integration test asserting protocols are valid semver.","Pin provider versions known to return well-formed metadata via the lock file."],"tags":["terraform","registry","provider-version","semver","protocol-version"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}