OpenNHP/opennhp · error

unexpected status code when download HRK

Error message

unexpected status code when download HRK: %d

What it means

verifyCertChain checks that the HRK download from https://cert.hygon.cn/hrk returned HTTP 200; any other status produces this error with the numeric status code. The library received a valid HTTP response but the server refused or failed the request, so the body is not treated as an HRK.

Solutions

  1. Check the reported status code and retry after an interval if it is 429/5xx.
  2. Cache the HRK persistently (disk) after first successful download so repeated verifications do not hit the server.
  3. Inspect the response from curl -i https://cert.hygon.cn/hrk to see whether a proxy or block page is intercepting.
  4. Pin the HRK blob locally (validated against the known digest f5a46663...) to remove runtime dependence on the remote server.
  5. If a redirect is being rejected (some 3xx), follow redirects explicitly or use a client configured to do so.

Example fix

// before
if resp.StatusCode != http.StatusOK {
	return fmt.Errorf("unexpected status code when download HRK: %d", resp.StatusCode)
}
// after: retry on transient statuses, fail on permanent ones
if resp.StatusCode == http.StatusTooManyRequests || resp.StatusCode >= 500 {
	time.Sleep(backoff)
	// retry the request
} else if resp.StatusCode != http.StatusOK {
	return fmt.Errorf("unexpected status code when download HRK: %d", resp.StatusCode)
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight the endpoint status
resp, err := http.Get("https://cert.hygon.cn/hrk")
if err == nil && resp.StatusCode != http.StatusOK {
	log.Printf("HRK endpoint unhealthy: %d", resp.StatusCode)
}

Try / catch

if err := att.Verify(chipId); err != nil {
	var status int
	if n, _ := fmt.Sscanf(err.Error(), "unexpected status code when download HRK: %d", &status); n == 1 && (status == 429 || status >= 500) {
		time.Sleep(5 * time.Second)
		return att.Verify(chipId) // bounded retries recommended
	}
	return err
}

Prevention

When it happens

Trigger: First verifyCertChain call when a.hrk is nil and the response status from https://cert.hygon.cn/hrk is not 200 OK — e.g. 403 (geo/IP blocked), 404, 429 (rate limited), 5xx (server outage), or 302 responses that http.Get does not follow to a 200.

Common situations: Hygon cert server outage or maintenance; rate limiting after many attestations (HRK is not cached across processes); region-based blocking outside China; a captive portal or proxy returning 401/403 HTML.

Related errors


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

Appendix: source

Thrown at nhp/core/verifier/csv/csv.go:302

	if VerifySignature(pubKey, msgAllDigest, rBig, sBig) {
		return nil
	} else {
		return fmt.Errorf("failed to verify signature")
	}
}

func (a *Attestation) verifyCertChain(chipId string) error {
	// Download HRK from Hygon's certificate server
	if a.hrk == nil {
		resp, err := http.Get("https://cert.hygon.cn/hrk")
		if err != nil {
			return fmt.Errorf("failed to download HRK: %v", err)
		}
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			return fmt.Errorf("unexpected status code when download HRK: %d", resp.StatusCode)
		}

		// Read the response body (HRK content)
		hrkData, err := io.ReadAll(resp.Body)
		if err != nil {
			return fmt.Errorf("failed to read HRK data: %v", err)
		}

		a.hrk = hrkData
	}

	digest, err := Sm3Digest(a.hrk)
	if err != nil {
		return err
	}

	expectedDigest, _ := hex.DecodeString("f5a46663059fdb4cdd06d097ed21782142923bb3430b3b938f23d54292094e3a")
	if !bytes.Equal(digest, expectedDigest) {

View on GitHub (pinned to 6e04ca5ff0)