hashicorp/packer · error

failed to build index request: %w

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.

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)

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.