OpenNHP/opennhp · error

failed to download file

Error message

failed to download file (%s): status code %s

What it means

DownloadFileToTemp in nhp/utils/utils.go performs an HTTP GET and requires HTTP 200. Any other status (404, 403, 500, etc.) aborts the download and returns this formatted error containing the URL and the response status string. The body is not consumed; the transfer is treated as failed.

Solutions

  1. Check the embedded status code and URL — verify the file exists at that URL (curl -I)
  2. Renew/refresh credentials or signed URLs if 403/401
  3. Add retry with backoff for transient 5xx responses
  4. Fix the configured base URL/path if 404

Example fix

// before
path, err := DownloadFileToTemp(expiredSignedURL, dir)
// after
url := refreshSignedURL(key) // regenerate pre-signed URL before each fetch
path, err := DownloadFileToTemp(url, dir)
Defensive patterns

Strategy: retry

Validate before calling

u, err := url.Parse(fileUrl); if err != nil || u.Scheme == "" || u.Host == "" { return fmt.Errorf("bad download url") }

Try / catch

var path string
var err error
for i := 0; i < 3; i++ {
    path, err = DownloadFileToTemp(url, dir)
    if err == nil { break }
    if strings.Contains(err.Error(), "status code 5") { time.Sleep(backoff(i)); continue }
    return err // 4xx: do not retry
}

Prevention

When it happens

Trigger: Calling DownloadFileToTemp(fileUrl, ...) where the server responds non-200: attestation/policy/data URLs that are stale, expired signed URLs (403), moved endpoints (404), or server-side errors (5xx).

Common situations: Expired pre-signed S3 URLs used by RefreshDataAccess/GetPolicy; wrong base URL or port in config; behind a proxy returning 407; service temporarily down (503) during deployments.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/15807aca75980d28. Report an issue: GitHub.

Appendix: source

Thrown at nhp/utils/utils.go:86

	}

	fileName := filepath.Base(fileUrl)
	tempFilePath := filepath.Join(tempDir, fileName)

	outFile, err := os.Create(tempFilePath)
	if err != nil {
		return "", err
	}
	defer outFile.Close()

	resp, err := http.Get(fileUrl) //nolint:gosec // G107: URL comes from trusted configuration
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("failed to download file (%s): status code %s", fileUrl, resp.Status)
	}

	_, err = io.Copy(outFile, resp.Body)
	if err != nil {
		return "", err
	}

	return tempFilePath, nil
}

func GenerateTempFilePath(pattern string) (string, error) {
	file, err := os.CreateTemp("", pattern)
	if err != nil {
		return "", err
	}

	tempPath := file.Name()

View on GitHub (pinned to 6e04ca5ff0)