OpenNHP/opennhp · error
failed to unmarshal data private key wrapping
Error message
failed to unmarshal data private key wrapping: %v
What it means
The WrappedDataKey field of the DAG message (dagMsg.Kao.WrappedDataKey) is expected to be a JSON DataPrivateKeyWrapping object; if json.Unmarshal fails the agent cannot unwrap the data private key and returns this error. It indicates malformed or unexpected key-wrapping payload from the data provider.
Solutions
- Log the raw WrappedDataKey content to see what was actually received
- Verify the producer side serializes a JSON DataPrivateKeyWrapping (not base64-of-JSON); decode first if double-encoded
- Check ztdolib.DataPrivateKeyWrapping schema vs the provider's version and upgrade aligning both sides
Example fix
// before
dataPrkWrapping := ztdolib.DataPrivateKeyWrapping{}
json.Unmarshal([]byte(dagMsg.Kao.WrappedDataKey), &dataPrkWrapping)
// after
raw, err := base64.StdEncoding.DecodeString(dagMsg.Kao.WrappedDataKey)
if err != nil { raw = []byte(dagMsg.Kao.WrappedDataKey) }
dataPrkWrapping := ztdolib.DataPrivateKeyWrapping{}
if err := json.Unmarshal(raw, &dataPrkWrapping); err != nil { return "", err } Defensive patterns
Strategy: type-guard
Validate before calling
raw := dagMsg.Kao.WrappedDataKey
if raw == "" || (!strings.HasPrefix(raw, "{") && !isB64JSON(raw)) {
return fmt.Errorf("WrappedDataKey is not a JSON DataPrivateKeyWrapping")
} Type guard
func isB64JSON(s string) bool {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil { return false }
return json.Valid(b)
} Try / catch
out, err := a.StartConfidentialComputing(ztdoId, ...)
if err != nil && strings.Contains(err.Error(), "data private key wrapping") {
log.Errorf("bad key wrapping from provider: %v", err)
// verify provider serialization format / ztdo version
} Prevention
- Agree on and version the DataPrivateKeyWrapping JSON schema between provider and agent
- Reject empty WrappedDataKey fields early at message receipt
- Add round-trip tests producing and consuming wrapped keys across versions
When it happens
Trigger: StartConfidentialComputing path where dagMsg.Kao.WrappedDataKey is empty, truncated, base64/binary instead of JSON, or JSON of a different schema.
Common situations: Data provider produced the ztdo with an older/incompatible wrapping format; WrappedDataKey field double-encoded (base64 of JSON); upstream message corruption.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- fail to unmarshal confidential computing result
- failed to unwrap data private key
- Failed to refresh SDP
- Error: fail to find policyId for ztdoId
- fail to call trusted application with error
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/eb162e5516243b43.
Report an issue: GitHub.
Appendix: source
Thrown at endpoints/agent/udpagent.go:1360
if result {
a.trustedByNHPDB.Store(true) // agent has been trusted by NHP DB
// update smart data policy refresh time
a.smartDataPolicyRefreshTime[ztdoId] = time.Now().UnixNano()
log.Info("[StartConfidentialComputing] Refresh smart data policy for data object which id is %s", ztdoId)
if !decrypted {
output, err = utils.GenerateTempFilePath("plaintext-*")
if err != nil {
return "", fmt.Errorf("Error: fail to generating temporary file path: %w", err)
}
dataPrkWrapping := ztdolib.DataPrivateKeyWrapping{}
if err := json.Unmarshal([]byte(dagMsg.Kao.WrappedDataKey), &dataPrkWrapping); err != nil {
log.Error("failed to unmarshal data private key wrapping: %v\n", err)
return "", fmt.Errorf("failed to unmarshal data private key wrapping: %v", err)
}
providerPbk, _ := base64.StdEncoding.DecodeString(dataPrkWrapping.ProviderPublicKeyBase64)
if dagMsg.AccessUrl == "" {
log.Error("access url is empty, please check with data provider")
return "", fmt.Errorf("access url is empty, please check with data provider")
}
var err error
ztdoPath, err := utils.DownloadFileToTemp(dagMsg.AccessUrl, "ztdo-")
if err != nil {
log.Error("failed to download ztdo: %v\n", err)
return "", fmt.Errorf("failed to download ztdo: %v", err)
}
if parseErr := ztdo.ParseHeader(ztdoPath); parseErr != nil {
fmt.Printf("Error: failed to parse ztdo header:%s\n", parseErr)View on GitHub (pinned to 6e04ca5ff0)