{"record":{"id":"c79f5b11c7918950","repo":"hashicorp/packer","slug":"no-stable-packer-releases-found-in-index-at-s","errorCode":null,"errorMessage":"no stable Packer releases found in index at %s","messagePattern":"no stable Packer releases found in index at (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/packer_release_fetch.go","lineNumber":91,"sourceCode":"\terr = json.NewDecoder(resp.Body).Decode(&indexData)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to retrieve packer release index from %s: %w\", indexURL, err)\n\t}\n\n\tvar semverList []*semver.Version\n\tfor vStr := range indexData.Versions {\n\t\tv, parseErr := semver.NewVersion(vStr)\n\t\tif parseErr != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif v.Prerelease() != \"\" {\n\t\t\tcontinue // skip alpha/beta/rc\n\t\t}\n\t\tsemverList = append(semverList, v)\n\t}\n\n\tif len(semverList) == 0 {\n\t\treturn \"\", fmt.Errorf(\"no stable Packer releases found in index at %s\", indexURL)\n\t}\n\n\tsort.Sort(semver.Collection(semverList))\n\tlatest := semverList[len(semverList)-1]\n\tlog.Printf(\"[INFO] Latest stable Packer version from releases index: %s\", latest.Original())\n\treturn latest.Original(), nil\n}\n\n// downloadURLToTempFile downloads url into a new temp file and returns its path.\n// On any error the temp file is removed. The caller owns the returned file on success.\nfunc downloadURLToTempFile(ctx context.Context, client *http.Client, url, suffix string) (string, error) {\n\tf, err := os.CreateTemp(\"\", \"packer-dl-*\"+suffix)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create temp file: %w\", err)\n\t}\n\ttmpPath := f.Name()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/packer_release_fetch.go#L73-L109","documentation":"fetchLatestPackerVersion downloads the HashiCorp releases index (releases.hashicorp.com/packer/index.json), parses every version key with Masterminds/semver, and filters out any version carrying a prerelease suffix (alpha/beta/rc). If after that filtering no version remains, it throws this error because there is nothing to sort or select as the latest stable release. It is a guard against an empty/invalid index rather than a download failure — the HTTP fetch and JSON decode already succeeded.","triggerScenarios":"The index JSON decoded successfully but its 'versions' map is empty, contains only keys that semver.NewVersion cannot parse (malformed keys), or contains only prerelease versions (all keys have a -alpha/-beta/-rc suffix) so every candidate is skipped by the 'skip alpha/beta/rc' filter.","commonSituations":"A proxy, mirror, or corporate artifact store serves a truncated, stale, or rewritten index.json (e.g. only 1.11.0-dev entries cached); the base URL is overridden to a mock/fixture with an empty versions map; HashiCorp publishes only prerelease builds to the index; a malicious or corrupted index contains garbage version keys.","solutions":["Check that the releases index is reachable and real: curl https://releases.hashicorp.com/packer/index.json and confirm the versions map contains stable entries like \"1.13.0\".","If using a proxy or mirror, ensure it caches the full index and does not strip stable versions or serve an empty/fixture document.","If pointing the code at a custom index URL for testing, populate the fixture with at least one valid stable semver key (no prerelease suffix).","Inspect the raw JSON for malformed version keys or unexpected structure and re-fetch; a corrupted cache should be purged.","If only prereleases exist upstream, wait for the next stable release or pin/hardcode a known-good version instead of resolving from the index."],"exampleFix":"// before: error surfaces only at runtime deep in the build\nlatest, err := fetchLatestPackerVersion(ctx, client)\n// after: sanity-check the index yourself before relying on dynamic resolution\nresp, _ := client.Get(\"https://releases.hashicorp.com/packer/index.json\")\nvar idx releaseIndex\njson.NewDecoder(resp.Body).Decode(&idx)\nhasStable := false\nfor k := range idx.Versions {\n    if v, err := semver.NewVersion(k); err == nil && v.Prerelease() == \"\" {\n        hasStable = true\n        break\n    }\n}\nif !hasStable {\n    return errors.New(\"release index has no stable versions; pin Packer version explicitly\")\n}","handlingStrategy":"validation","validationCode":"// Check the release index yourself before invoking the fetch path\nresp, err := http.Get(\"https://releases.hashicorp.com/packer/index.json\")\nif err != nil { return err }\nvar idx struct{ Versions map[string]json.RawMessage `json:\"versions\"` }\nif err := json.NewDecoder(resp.Body).Decode(&idx); err != nil { return err }\nresp.Body.Close()\nhasStable := false\nfor k := range idx.Versions {\n    if v, err := semver.NewVersion(k); err == nil && v.Prerelease() == \"\" {\n        hasStable = true\n        break\n    }\n}\nif !hasStable {\n    return fmt.Errorf(\"release index has no stable Packer versions; pin a version instead\")\n}","typeGuard":"// Ensure a parsed version is usable as the latest stable release\nfunc isStableVersion(k string) bool {\n    v, err := semver.NewVersion(k)\n    return err == nil && v.Prerelease() == \"\"\n}","tryCatchPattern":null,"preventionTips":["Sanity-check custom/mirrored index URLs with curl before wiring them into builds.","Pin a Packer version in CI when you cannot tolerate upstream index anomalies.","Alert on index.json contents in monitoring so an empty/stale mirror is caught early.","Keep TMPDIR/network healthy so you never fall back to untrusted mirrors.","Log the full version list at debug level to make empty-filter regressions obvious."],"tags":["http","semver","releases-index","packer"],"backgroundTag":"empty-release-index","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}