{"record":{"id":"3a476daad76af88e","repo":"OpenNHP/opennhp","slug":"ztdo-id-mismatch-please-check-with-data-provider","errorCode":null,"errorMessage":"ztdo id mismatch, please check with data provider","messagePattern":"ztdo id mismatch, please check with data provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/agent/udpagent.go","lineNumber":1384,"sourceCode":"\t\t\t\tlog.Error(\"access url is empty, please check with data provider\")\n\t\t\t\treturn \"\", fmt.Errorf(\"access url is empty, please check with data provider\")\n\t\t\t}\n\n\t\t\tvar err error\n\t\t\tztdoPath, err := utils.DownloadFileToTemp(dagMsg.AccessUrl, \"ztdo-\")\n\t\t\tif err != nil {\n\t\t\t\tlog.Error(\"failed to download ztdo: %v\\n\", err)\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to download ztdo: %v\", err)\n\t\t\t}\n\n\t\t\tif parseErr := ztdo.ParseHeader(ztdoPath); parseErr != nil {\n\t\t\t\tfmt.Printf(\"Error: failed to parse ztdo header:%s\\n\", parseErr)\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to parse ztdo header:%s\", parseErr)\n\t\t\t}\n\n\t\t\tif ztdoId != ztdo.GetObjectID() {\n\t\t\t\tfmt.Printf(\"Error: ztdo id mismatch, please check with data provider\\n\")\n\t\t\t\treturn \"\", fmt.Errorf(\"ztdo id mismatch, please check with data provider\")\n\t\t\t}\n\n\t\t\t// decrypt data private key\n\t\t\tsaDataPrk := ztdolib.NewSymmetricAgreement(ztdo.GetECCMode(), false)\n\t\t\tsaDataPrk.SetMessagePatterns(ztdolib.DataPrivateKeyWrappingPatterns)\n\t\t\tsaDataPrk.SetPsk([]byte(ztdolib.InitialDHPKeyWrappingString))\n\t\t\tsaDataPrk.SetStaticKeyPair(teeEcdh)\n\t\t\tsaDataPrk.SetEphemeralKeyPair(consumerEphemeralEcdh)\n\t\t\tsaDataPrk.SetRemoteStaticPublicKey(providerPbk)\n\n\t\t\tgcmKey, ad := saDataPrk.AgreeSymmetricKey()\n\n\t\t\tdataPrkBase64, err := dataPrkWrapping.Unwrap(gcmKey[:], ad)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to unwrap data private key: %s\", err)\n\t\t\t}\n\n\t\t\tif ztdoPath == \"\" || output == \"\" {","sourceCodeStart":1366,"sourceCodeEnd":1402,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/agent/udpagent.go#L1366-L1402","documentation":"After parsing the header, the agent compares the requested ztdoId with the object id embedded in the downloaded ztdo header (ztdo.GetObjectID()). A mismatch means the provider returned data for a different object than requested, or the stored header was rewritten. Treated as an integrity check failure and surfaced as 'check with data provider'.","triggerScenarios":"dagMsg carries a ztdo whose header object id differs from the ztdoId the agent requested — e.g. the DB/provider overwrote a record with a new ztdo id, or the wrong record was served due to an id collision/typo.","commonSituations":"Provider re-encrypted data and updated the ztdo id but the DB still serves the old URL; client passes the wrong ztdo-id to a cached/misrouted DB entry; concurrent writers overwriting the same object storage key.","solutions":["Confirm the exact ztdo-id requested matches the id the provider intends to serve.","Ask the provider to re-encrypt/re-publish so the header object id matches the registered ztdo id.","Clear any stale DB record/URL mapping pointing to the wrong object.","Re-run the request after the provider fixes the record; verify the header id with a local parse."],"exampleFix":"// before: mismatch surfaces only at the agent\nif ztdoId != ztdo.GetObjectID() {\n    return \"\", fmt.Errorf(\"ztdo id mismatch, please check with data provider\")\n}\n\n// after: provider side sets the header id before upload\nif err := ztdo.SetObjectID(requestedZtdoId); err != nil {\n    return fmt.Errorf(\"cannot align header id with registered id: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if got := ztdo.GetObjectID(); got != ztdoId {\n    return fmt.Errorf(\"expected ztdo %s, provider returned %s\", ztdoId, got)\n}","typeGuard":"func matchesRequestedId(z *ztdo.Ztdo, id string) bool { return z != nil && z.GetObjectID() == id }","tryCatchPattern":"path, err := fetchZtdo(ctx, ztdoId)\nvar idm *ZtdoIdMismatchError\nif errors.As(err, &idm) {\n    // notify provider with both ids for reconciliation\n}","preventionTips":["Providers must regenerate/republish the record whenever the header object id changes.","Avoid concurrent writers to the same object storage key.","Log both requested and returned ids to speed up reconciliation."],"tags":["ztdo","data-integrity","id-mismatch","dhp"],"backgroundTag":"checksum-mismatch","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"}