OpenNHP/opennhp · error

Failed to refresh SDP

Error message

Failed to refresh SDP: %s

What it means

In the confidential-computing data access flow, if PreCheckDataAccess indicates the smart data policy (SDP) must be refreshed, the agent calls RefreshDataAccess; any failure there is wrapped as 'Failed to refresh SDP'. It means the agent could not obtain/update the current policy needed before invoking the trusted application.

Solutions

  1. Inspect the wrapped inner error (the %s payload) for the root cause (network, auth, policy)
  2. Verify the ztdoId exists and the agent can reach the NHP server/AC
  3. Retry after re-knocking or re-establishing the NHP channel so the policy refresh can succeed
Defensive patterns

Strategy: retry

Validate before calling

// ensure channel is reachable before data access
if a.device == nil || a.device.GetDecryptedMsgQueue() == nil {
    return fmt.Errorf("agent channel not established; knock first")
}

Try / catch

output, err := a.AccessData(ztdoId, ...)
if err != nil && strings.Contains(err.Error(), "Failed to refresh SDP") {
    // re-knock / re-establish session then retry once
    if err := a.Knock(); err == nil {
        output, err = a.AccessData(ztdoId, ...)
    }
}

Prevention

When it happens

Trigger: AccessData flow where PreCheckDataAccess(ztdoId) sets refreshSdp=true (policy expired/absent) and RefreshDataAccess then fails — e.g. AC/server unreachable, ztdoId unknown, or policy decryption failing.

Common situations: Expired smart data policy during long-running sessions; network/auth problems with the NHP server; ztdoId typo or object deleted upstream.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at endpoints/agent/udpagent.go:1276

}

func (a *UdpAgent) StartConfidentialComputing(ztdoId string, taId string, function string, params map[string]any) (any, error) {
	var err error
	var policyId string

	output, refreshSdp, decrypted := a.PreCheckDataAccess(ztdoId)

	if refreshSdp {
		a.dataAccessRefreshMutex.Lock()
		defer a.dataAccessRefreshMutex.Unlock()

		// secondly check again
		output, refreshSdp, decrypted = a.PreCheckDataAccess(ztdoId)

		if refreshSdp {
			output, err = a.RefreshDataAccess(ztdoId, decrypted, output)
			if err != nil {
				return nil, fmt.Errorf("Failed to refresh SDP: %s", err.Error())
			}
		}
	}

	// inject data path to params
	params["path"] = output

	var exist bool
	if policyId, exist = a.smartPolicyIdentifier[ztdoId]; !exist {
		return nil, fmt.Errorf("Error: fail to find policyId for ztdoId %s.\n", ztdoId)
	}

	taRes, err := a.CallTrustedApplication(taId, function, params, policyId)
	if err != nil {
		return nil, fmt.Errorf("fail to call trusted application with error: %s\n", err.Error())
	} else {
		var structResult map[string]any

View on GitHub (pinned to 6e04ca5ff0)