OpenNHP/opennhp · error
failed to read HRK data
Error message
failed to read HRK data: %v
What it means
verifyCertChain reads the HRK response body with io.ReadAll; if reading the stream fails it wraps the error here. The HTTP response was successful (status 200) but the body could not be fully read — typically a dropped connection mid-body or a reader/timeout error.
Solutions
- Retry the download; this error is usually transient.
- Use an HTTP client with a sane timeout and retry/backoff policy instead of http.Get's defaults.
- Validate the HRK digest after download (the code already checks a fixed SM3 digest) so partial bodies are caught even when reads succeed.
- Persist a known-good HRK locally and fall back to it when the fetch fails.
- Check whether a proxy/CDN in the path is truncating responses (compare Content-Length vs bytes read).
Example fix
// before
hrkData, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read HRK data: %v", err)
}
// after: retry once on transient read failure
hrkData, err := io.ReadAll(resp.Body)
if err != nil {
resp2, gerr := client.Get(hrkURL)
if gerr == nil {
defer resp2.Body.Close()
hrkData, err = io.ReadAll(resp2.Body)
}
if err != nil {
return fmt.Errorf("failed to read HRK data: %v", err)
}
} Defensive patterns
Strategy: retry
Validate before calling
// verify a cached HRK is complete before trusting it
func hrkLooksValid(data []byte) bool {
return len(data) >= 0x2a8 // must contain all fields the verifier slices
} Try / catch
if err := att.Verify(chipId); err != nil {
if strings.Contains(err.Error(), "failed to read HRK data") {
time.Sleep(backoff)
return att.Verify(chipId) // transient mid-body read failure
}
return err
} Prevention
- Use an HTTP client with explicit timeouts instead of http.Get defaults.
- Retry transient body-read failures automatically.
- Always validate the downloaded HRK against its pinned SM3 digest before use.
- Investigate middleboxes/proxies if truncation recurs.
When it happens
Trigger: First verifyCertChain call when a.hrk is nil, the GET to https://cert.hygon.cn/hrk returned 200, but io.ReadAll(resp.Body) fails due to connection reset mid-transfer, TLS read error, response body truncation, or an intervening proxy that closes the connection.
Common situations: Unstable network links (mobile/VPN); aggressive middleboxes or proxies that cut long responses; server-side timeouts writing the body; containerized environments with short idle timeouts.
Related errors
- could not read response body
- failed to download HRK
- unexpected status code when download HRK
- failed to read response body
- failed to download ztdo
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/ab3fbe24611db6d2.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/verifier/csv/csv.go:308
}
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) {
return fmt.Errorf("HRK digest verification failed: got %x, want %x", digest, expectedDigest)
}
if err := a.verifyHygonCertInfo(a.hrk, 0x03, 0, a.hrk[0x04:0x14]); err != nil {
return err
}View on GitHub (pinned to 6e04ca5ff0)