{"record":{"id":"aade986a227f3f3f","repo":"hashicorp/terraform","slug":"registry-response-includes-invalid-protocol-string","errorCode":null,"errorMessage":"registry response includes invalid protocol string %q: %s","messagePattern":"registry response includes invalid protocol string %q: (.+?)","errorType":"exception","errorClass":"ErrQueryFailed","httpStatus":null,"severity":"error","filePath":"internal/getproviders/registry_client.go","lineNumber":395,"sourceCode":"\t\tv, err := ParseVersion(versionStr)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"[WARN] registry response includes invalid version string %q. skipping: %s\", versionStr, err)\n\t\t\tcontinue\n\t\t}\n\t\tversionList = append(versionList, v)\n\t}\n\tversionList.Sort() // lowest precedence first, preserving order when equal precedence\n\n\tprotoVersions := MeetingConstraints(SupportedPluginProtocols)\nFindMatch:\n\t// put the versions in increasing order of precedence\n\tfor index := len(versionList) - 1; index >= 0; index-- { // walk backwards to consider newer versions first\n\t\tfor _, protoStr := range available[versionList[index].String()] {\n\t\t\tp, err := ParseVersion(protoStr)\n\t\t\tif err != nil {\n\t\t\t\treturn UnspecifiedVersion, ErrQueryFailed{\n\t\t\t\t\tProvider: provider,\n\t\t\t\t\tWrapped:  fmt.Errorf(\"registry response includes invalid protocol string %q: %s\", protoStr, err),\n\t\t\t\t}\n\t\t\t}\n\t\t\tif protoVersions.Has(p) {\n\t\t\t\tmatch = versionList[index]\n\t\t\t\tbreak FindMatch\n\t\t\t}\n\t\t}\n\t}\n\treturn match, nil\n}\n\nfunc (c *registryClient) addHeadersToRequest(req *http.Request) {\n\tif c.creds != nil {\n\t\tc.creds.PrepareRequest(req)\n\t}\n\treq.Header.Set(terraformVersionHeader, version.String())\n}\n","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/getproviders/registry_client.go#L377-L413","documentation":"Returned as ErrQueryFailed when a provider version listed by the registry advertises a protocol version string that fails ParseVersion (semver-like parsing). The '%q' is the bad protocol string and '%s' is the parse error. The registry contract requires each version's 'protocols' array to contain valid semver strings (e.g. '5.0', '6.0'); any malformed entry aborts the closest-protocol search.","triggerScenarios":"c.ProviderVersions returns a map whose inner 'protocols' array contains a non-semver token such as 'v5', '5.x', 'latest', or an empty string, and that version is reached during the backwards precedence walk in findClosestProtocolCompatibleVersion.","commonSituations":"Custom or private registry emitting 'protocols': ['v5.0'] instead of ['5.0']; a registry returning a 'latest' sentinel; partial JSON where a field was misnamed and decodes to an empty string; version skew after a registry API change.","solutions":["Inspect the registry's /v1/providers/<addr>/versions response and correct the 'protocols' array entries to valid semver.","Ensure the registry emits bare versions like '5.0' / '6.0' without a 'v' prefix or range operators.","If you control the registry, add server-side validation to reject malformed protocol strings before publication.","Pin the provider version explicitly in required_providers to avoid triggering closest-protocol fallback on bad metadata."],"exampleFix":"// before (registry JSON)\n{\"versions\":[{\"version\":\"1.0.0\",\"protocols\":[\"v5.0\"]}]}\n// after\n{\"versions\":[{\"version\":\"1.0.0\",\"protocols\":[\"5.0\"]}]}","handlingStrategy":"validation","validationCode":"// Validate a 'protocols' array before publishing a registry response.\nfunc validateProtocols(protos []string) error {\n    for _, p := range protos {\n        if _, err := getproviders.ParseVersion(p); err != nil {\n            return fmt.Errorf(\"invalid protocol %q: %w\", p, err)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Publish registry metadata through tooling that validates semver protocol strings.","Pin required_providers versions to avoid closest-protocol fallback over bad metadata.","Add CI schema tests for private registry responses."],"tags":["registry","semver","protocol-version","validation","getproviders"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}