OpenNHP/opennhp · error

access url is empty, please check with data provider

Error message

access url is empty, please check with data provider

What it means

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.

Solutions

  1. Verify with the data provider that the ztdo object was actually uploaded and an access URL was registered for this ztdo-id.
  2. Re-run the encrypt step (nhp-db main encrypt mode) ensuring --source and --output are provided so the access URL gets populated.
  3. Check the NHP-DB/provider logs for the ztdo id to confirm the record exists and contains a URL.
  4. Confirm the agent is querying the correct NHP-DB server/cluster (peer config) hosting the data.

Example fix

// before: agent fails on empty URL
ztdoPath, err := utils.DownloadFileToTemp(dagMsg.AccessUrl, "ztdo-")

// after: guard on the provider side before publishing
if provider.AccessUrl == "" {
    return fmt.Errorf("cannot publish ztdo %s: access url not yet generated", ztdoId)
}
Defensive patterns

Strategy: validation

Validate before calling

if dagMsg.ErrCode == 0 && dagMsg.AccessUrl == "" {
    return fmt.Errorf("provider returned no access url for ztdo %s", ztdoId)
}

Type guard

func hasAccessUrl(m *common.DataAckMsg) bool { return m != nil && m.AccessUrl != "" }

Try / catch

path, err := getZtdo(ctx, ztdoId)
if errors.Is(err, errEmptyAccessUrl) {
    // surface 'contact data provider' to user, skip download
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/0da645fd38d6e44f. Report an issue: GitHub.

Appendix: source

Thrown at endpoints/agent/udpagent.go:1367

		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)
				return "", fmt.Errorf("failed to parse ztdo header:%s", parseErr)
			}

			if ztdoId != ztdo.GetObjectID() {
				fmt.Printf("Error: ztdo id mismatch, please check with data provider\n")
				return "", fmt.Errorf("ztdo id mismatch, please check with data provider")
			}

View on GitHub (pinned to 6e04ca5ff0)