hashicorp/packer · error

failed to build index request

Error message

failed to build index request: %w

What it means

The hcp-sbom provisioner could not construct the http.Request used to query the Packer releases index (`https://releases.hashicorp.com/packer/index.json`). `http.NewRequestWithContext` returns an error only when the URL fails to parse (or the method/body are invalid). This wraps that error with context so callers know the request was never sent.

Solutions

  1. Confirm the release base URL used to compose the index URL is a well-formed absolute URL with an http/https scheme.
  2. Check for stray whitespace or control characters in any environment/config value feeding the base URL.
  3. Log the wrapped underlying error (`%w`) — it names the exact parse failure (e.g. `parse "...": invalid control character in URL`).
  4. Verify no proxy/URL-mangling middleware or wrapper replaced getReleaseBaseURL with a bad value.

Example fix

// before (malformed override)
baseURL := "releases.hashicorp.com" // missing scheme

// after
baseURL := "https://releases.hashicorp.com"
Defensive patterns

Strategy: try-catch

Validate before calling

u, err := url.Parse(baseURL + "/packer/index.json")
if err != nil || u.Scheme == "" || u.Host == "" {
	return fmt.Errorf("invalid release index URL: %q", baseURL+"/packer/index.json")
}

Type guard

func isRequestConstructionError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "failed to build index request")
}

Try / catch

ver, err := fetchLatestPackerVersion(ctx, client)
if err != nil {
	var urlErr *url.Error
	if errors.As(err, &urlErr) {
		log.Fatalf("malformed release URL: %v", urlErr)
	}
	return err
}

Prevention

When it happens

Trigger: fetchLatestPackerVersion builds the index URL from getReleaseBaseURL() and calls http.NewRequestWithContext; the error fires when that URL string is unparseable — e.g. an invalid/missing scheme or control characters in the URL. Not reachable with the default hardcoded HTTPS URL under normal operation; effectively only via URL construction failure or context misuse.

Common situations: Practically rare in production: a patched/overridden release base URL that is malformed, an empty URL from a bad configuration override, or URL containing illegal characters (spaces, newlines).

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/b82735aa710bc77e. Report an issue: GitHub.

Appendix: source

Thrown at provisioner/hcp-sbom/packer_release_fetch.go:60

}

// releaseBuild represents one platform build inside a release version.
type releaseBuild struct {
	OS       string `json:"os"`
	Arch     string `json:"arch"`
	Filename string `json:"filename"`
	URL      string `json:"url"`
}

// fetchLatestPackerVersion queries the HashiCorp releases index, sorts all
// stable (non-prerelease) versions with semver, and returns the highest one.
func fetchLatestPackerVersion(ctx context.Context, client *http.Client) (string, error) {
	indexURL := getReleaseBaseURL() + "/packer/index.json"
	var indexData releaseIndex

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, indexURL, nil)
	if err != nil {
		return "", fmt.Errorf("failed to build index request: %w", err)
	}

	resp, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("failed to fetch release index: %w", err)
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("HTTP %d for %s", resp.StatusCode, indexURL)
	}

	err = json.NewDecoder(resp.Body).Decode(&indexData)
	if err != nil {
		return "", fmt.Errorf("failed to retrieve packer release index from %s: %w", indexURL, err)
	}

	var semverList []*semver.Version

View on GitHub (pinned to eb36e3c3e4)