{"record":{"id":"0da645fd38d6e44f","repo":"OpenNHP/opennhp","slug":"access-url-is-empty-please-check-with-data-provid","errorCode":null,"errorMessage":"access url is empty, please check with data provider","messagePattern":"access url is empty, please check with data provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/agent/udpagent.go","lineNumber":1367,"sourceCode":"\n\t\tif !decrypted {\n\t\t\toutput, err = utils.GenerateTempFilePath(\"plaintext-*\")\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"Error: fail to generating temporary file path: %w\", err)\n\t\t\t}\n\n\t\t\tdataPrkWrapping := ztdolib.DataPrivateKeyWrapping{}\n\n\t\t\tif err := json.Unmarshal([]byte(dagMsg.Kao.WrappedDataKey), &dataPrkWrapping); err != nil {\n\t\t\t\tlog.Error(\"failed to unmarshal data private key wrapping: %v\\n\", err)\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to unmarshal data private key wrapping: %v\", err)\n\t\t\t}\n\n\t\t\tproviderPbk, _ := base64.StdEncoding.DecodeString(dataPrkWrapping.ProviderPublicKeyBase64)\n\n\t\t\tif dagMsg.AccessUrl == \"\" {\n\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}","sourceCodeStart":1349,"sourceCodeEnd":1385,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/agent/udpagent.go#L1349-L1385","documentation":"Raised in the agent's DHP ztdo retrieval flow (udpagent.go) when the DAG message returned by the NHP-DB data broker carries an empty AccessUrl. The agent cannot download the encrypted ztdo payload without a URL, so it fails fast and asks the developer to check with the data provider. It indicates the provider/DB side did not populate the access URL for this ztdo id.","triggerScenarios":"Agent sends a ztdo request via UDP; the returned dagMsg has ErrCode == 0 (success) but dagMsg.AccessUrl == \"\". Typically the DB/provider never uploaded or registered the data, or the provider omitted the access URL when creating/updating the ztdo record.","commonSituations":"Data provider encrypted/uploaded data out-of-band but never published the URL; a provider-public-key or ztdo-id typo resolves to a record with no payload; stale provider record after re-registration; DB misconfiguration where object storage is not set up.","solutions":["Verify with the data provider that the ztdo object was actually uploaded and an access URL was registered for this ztdo-id.","Re-run the encrypt step (nhp-db main encrypt mode) ensuring --source and --output are provided so the access URL gets populated.","Check the NHP-DB/provider logs for the ztdo id to confirm the record exists and contains a URL.","Confirm the agent is querying the correct NHP-DB server/cluster (peer config) hosting the data."],"exampleFix":"// before: agent fails on empty URL\nztdoPath, err := utils.DownloadFileToTemp(dagMsg.AccessUrl, \"ztdo-\")\n\n// after: guard on the provider side before publishing\nif provider.AccessUrl == \"\" {\n    return fmt.Errorf(\"cannot publish ztdo %s: access url not yet generated\", ztdoId)\n}","handlingStrategy":"validation","validationCode":"if dagMsg.ErrCode == 0 && dagMsg.AccessUrl == \"\" {\n    return fmt.Errorf(\"provider returned no access url for ztdo %s\", ztdoId)\n}","typeGuard":"func hasAccessUrl(m *common.DataAckMsg) bool { return m != nil && m.AccessUrl != \"\" }","tryCatchPattern":"path, err := getZtdo(ctx, ztdoId)\nif errors.Is(err, errEmptyAccessUrl) {\n    // surface 'contact data provider' to user, skip download\n}","preventionTips":["Verify provider uploads complete (URL registered) before distributing the ztdo-id.","Alert on DB records whose access_url column is empty.","Pin the exact ztdo-id in requests to avoid resolving stale records."],"tags":["network","dhp","ztdo","data-provider"],"backgroundTag":"empty-required-field","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"}