{"record":{"id":"49ed56242e8b8d10","repo":"OpenNHP/opennhp","slug":"failed-to-read-hsk-cek-data-v","errorCode":null,"errorMessage":"failed to read hsk_cek data: %v","messagePattern":"failed to read hsk_cek data: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/verifier/csv/csv.go","lineNumber":351,"sourceCode":"\t\ta.hrk[0xd6:0xd6+hrkIdLen], a.hrk[:0x240],\n\t); err != nil {\n\t\treturn err\n\t}\n\n\tif _, ok := a.hskCek[chipId]; !ok {\n\t\tresp, err := http.Get(fmt.Sprintf(\"https://cert.hygon.cn/hsk_cek?snumber=%s\", chipId))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to download hsk_cek: %v\", err)\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\treturn fmt.Errorf(\"unexpected status code when download hsk_cek: %d\", resp.StatusCode)\n\t\t}\n\n\t\thskCekData, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read hsk_cek data: %v\", err)\n\t\t}\n\n\t\ta.hskCek[chipId] = hskCekData\n\t}\n\n\thskData := a.hskCek[chipId][:0x340]\n\tcekData := a.hskCek[chipId][0x340:]\n\n\t// verify hsk cert info\n\tif err := a.verifyHygonCertInfo(hskData, 0x03, 0x13, a.hrk[0x04:0x14]); err != nil {\n\t\treturn err\n\t}\n\n\t// verify hsk cert signature (self-signed)\n\tif err := a.verifySm2SignatureWithId(\n\t\ta.hrk[0x44:0x64], a.hrk[0x8c:0xac],\n\t\ta.hskCek[chipId][0x240:0x260], a.hskCek[chipId][0x288:0x2a8],\n\t\ta.hrk[0xd6:0xd6+hrkIdLen], a.hskCek[chipId][:0x240],","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/verifier/csv/csv.go#L333-L369","documentation":"After a 200 response, verifyCertChain reads the full hsk_cek certificate blob from the response body with io.ReadAll. This error wraps any failure while consuming the body stream (connection reset mid-transfer, premature EOF, decompression/timeout errors). The cached download of the CEK therefore never completes.","triggerScenarios":"Calling Verify on CSV evidence requiring a live fetch when the TLS connection to cert.hygon.cn is interrupted before the body finishes downloading, the server closes the connection early, or a client-side timeout fires mid-body.","commonSituations":"Flaky mobile/VPN networks; Hygon CA closing idle or long transfers; middleboxes/proxies terminating large responses; extremely slow egress to the China-hosted endpoint causing timeouts.","solutions":["Retry the download; the failure is typically transient network interruption.","Use an http.Client with a sane Timeout and enable retries with backoff around io.ReadAll.","Pre-seed the hskCek cache with the CEK blob for known chipIds so attestation never depends on the network.","Check proxy/MTU/firewall issues if resets are persistent."],"exampleFix":"// before\nhskCekData, err := io.ReadAll(resp.Body)\nif err != nil {\n    return fmt.Errorf(\"failed to read hsk_cek data: %v\", err)\n}\n// after\nhskCekData, err := io.ReadAll(resp.Body)\nif err != nil {\n    if retriable(err) && attempts < 3 {\n        goto retry // or return a sentinel so the caller retries the whole fetch\n    }\n    return fmt.Errorf(\"failed to read hsk_cek data: %v\", err)\n}","handlingStrategy":"retry","validationCode":"// No meaningful pre-check; instead ensure the download completes before attestation:\ncek, err := fetchHskCek(chipId) // run ahead of Verify\nif err != nil || len(cek) < 0x680 {\n    return fmt.Errorf(\"prefetch of hsk_cek incomplete for %s\", chipId)\n}","typeGuard":null,"tryCatchPattern":"if err := attestation.Verify(ctx, evidence); err != nil {\n    if strings.Contains(err.Error(), \"failed to read hsk_cek data\") || errors.Is(err, io.ErrUnexpectedEOF) {\n        // transient stream failure: retry the whole verification with backoff\n    }\n}","preventionTips":["Use an HTTP client with a Timeout so partial reads fail fast and cleanly.","Retry idempotent GETs automatically on body-read errors.","Pre-seed the hskCek cache on stable network links before running attestations.","Avoid attesting over flaky VPN/mobile links; run the verifier on a reliable connection."],"tags":["network","io","attestation","response-body"],"backgroundTag":"network-request-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}