{"record":{"id":"8b1c7e4c75f6acdc","repo":"hashicorp/terraform","slug":"provider-mirror-does-not-have-archive-index-for-pr","errorCode":null,"errorMessage":"provider mirror does not have archive index for previously-reported %s version %s","messagePattern":"provider mirror does not have archive index for previously-reported (.+?) version (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/http_mirror_source.go","lineNumber":194,"sourceCode":"\t)\n\n\tstatusCode, body, finalURL, err := s.get(ctx, endpointPath)\n\tdefer func() {\n\t\tif body != nil {\n\t\t\tbody.Close()\n\t\t}\n\t}()\n\tif err != nil {\n\t\treturn PackageMeta{}, s.errQueryFailed(provider, err)\n\t}\n\n\tswitch statusCode {\n\tcase http.StatusOK:\n\t\t// Great!\n\tcase http.StatusNotFound:\n\t\t// A 404 Not Found for a version we previously saw in index.json is\n\t\t// a protocol error, so we'll report this as \"query failed.\n\t\treturn PackageMeta{}, s.errQueryFailed(provider, fmt.Errorf(\"provider mirror does not have archive index for previously-reported %s version %s\", provider, version))\n\tcase http.StatusUnauthorized, http.StatusForbidden:\n\t\treturn PackageMeta{}, s.errUnauthorized(finalURL)\n\tdefault:\n\t\treturn PackageMeta{}, s.errQueryFailed(provider, fmt.Errorf(\"server returned unsuccessful status %d\", statusCode))\n\t}\n\n\t// If we got here then the response had status OK and so our body\n\t// will be non-nil and should contain some JSON for us to parse.\n\tvar bodyContent ListInstallationPackagesResponseBody\n\n\tdec := json.NewDecoder(body)\n\tif err := dec.Decode(&bodyContent); err != nil {\n\t\treturn PackageMeta{}, s.errQueryFailed(provider, fmt.Errorf(\"invalid response content from mirror server: %s\", err))\n\t}\n\n\tarchiveMeta, ok := bodyContent.Archives[target.String()]\n\tif !ok {\n\t\treturn PackageMeta{}, ErrPlatformNotSupported{","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/http_mirror_source.go#L176-L212","documentation":"In PackageMeta, a 404 on the per-version JSON file is treated as a protocol violation because that version was previously advertised in index.json's version list. The mirror is internally inconsistent, so the query is failed (not silently skipped) with errQueryFailed wrapping this message.","triggerScenarios":"AvailableVersions returned version X for a provider, but GET <host>/<ns>/<type>/X.json then responds 404. Caused by a mirror whose index and per-version files are generated from different snapshots, partial sync, or a race where a version was pruned between the two calls.","commonSituations":"Mirror being updated while terraform init runs; mirror populated by a job that writes index.json before writing version files (or vice versa); manually edited mirror with stale index entries.","solutions":["Re-run once the mirror has finished publishing a consistent snapshot.","Fix the mirror publish pipeline so index.json and all version files are written atomically together.","If a version was deliberately removed, regenerate index.json so it no longer lists it."],"exampleFix":"# before: index.json lists 5.2.0 but 5.2.0.json is missing\ncurl https://mirror/tf/.../aws/5.2.0.json   # 404\n\n# after: regenerate the mirror index after adding/removing versions\n$ tf-provider-mirror sync --prune https://mirror/tf","handlingStrategy":"try-catch","validationCode":"// After AvailableVersions succeeds, probe each version file existence\n// before handing off to PackageMeta, to detect mirror inconsistency early.\nfor _, v := range versions {\n    if !mirrorHasVersionFile(p, v) { /* flag inconsistent version */ }\n}","typeGuard":null,"tryCatchPattern":"var qf getproviders.ErrQueryFailed\nif errors.As(err, &qf) && strings.Contains(qf.Error(), \"does not have archive index\") {\n    // mirror index/version mismatch: skip this version and report to operator\n}","preventionTips":["Publish index.json and all version files atomically as one snapshot.","Run mirror generation with --prune so removed versions leave no stale index entries.","Avoid updating a live mirror while terraform init runs."],"tags":["protocol","mirror","consistency"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}