Troubleshoot Trust Check denials

Find why a Trust Check policy refused a request, and tell a misconfiguration or connection problem from an agent the trust registry does not trust.

This guide finds why a request that a Trust Check policy refused got a 403, using the result code each Trust Check records. For how Trust Check results reach policy, see Trust registries.

A refused request has one of two causes. Either the trust registry answered that it does not recognise or authorise the agent, which is a real “not trusted” result, or the check could not complete, which points to a configuration or connection problem. The fix is different for each, so find the code before changing anything.

Use this guide when:

  • A surface with a Trust Check returns 403 to an agent you expected it to accept.
  • A partner’s surface refuses your agent, and you want to know whether your records or their configuration is the cause.

Prerequisites

  • A surface with a Trust Check and a Policy element that enforces it. See Agent validation via a trust registry.
  • A request that was refused, and roughly when it was sent.
  • The Administrator role, by default, to read the Audit page. Any role can read the Logs page.

Steps

Find the result code

Use either place:

  • Audit page: with Enable VP Auditing on and the Trust Check event selected in Settings › Security, select Trust Checks in Category. A refused check reads Trust check failed, followed by “Failed because” and the reason. For NOT_RECOGNIZED and NOT_AUTHORIZED the reason is the code itself. For the other codes it is a short description, listed in the Audit page shows column below. Select the record to see the leg, the Authority, the Entity, and the same reason under Failure.
  • Logs page: a check that fails or is denied is logged at WARN as trust check: denied or trust check: error, with the code in error_code. The Logs page always shows the code.
Audit page with a Trust check failed record that reads Failed because NOT_RECOGNIZED, below the Denied policy decision for the same request, and its event details showing the caller-leg Trust Check from the Authority DID to the caller's agent DID

Read the log sequence

A refused request usually leaves three lines. This one is for a caller whose agent the trust registry does not recognise:

2026-11-02T07:31:05.907Z  INFO Received response: https://affinidi.com/didcomm/protocols/trqp/1.0/query-recognition/response
2026-11-02T07:31:05.912Z  WARN trust check: denied surface_id="b96cff84-1bab-42dd-a923-cfc7cd46390e" transit_point="" leg="caller" element_id="trust-check-caller" element_name="Verify caller" trust_registry_id="7c1d2e4f-5a6b-4c8d-9e0f-1a2b3c4d5e6f" query_type="recognition" result="denied" ok=false error_code="NOT_RECOGNIZED" latency_ms=84
2026-11-02T07:31:05.931Z  WARN policy decision: deny policy_scope="surface" policy_flow="access_point" policy_decision="deny" policy_id="surface.policy" deny_reason="Caller is not a recognised agent" surface_id="b96cff84-1bab-42dd-a923-cfc7cd46390e" trace_id="4dfcbc74-9697-4e21-9434-d1a5045cdf80"
  • The Received response line confirms the trust registry answered.
  • The trust check line names the leg, the query type, and the result. result="denied" is the registry’s answer. result="error" means the query could not complete.
  • The policy decision line names the policy that refused the request and its deny_reason.
  • On a request through a Transit Point, leg="target" and transit_point names the Transit Point.

Passing checks and allowed decisions are logged at debug level, so at the default log level a successful request shows only the registry’s responses. To see every outcome, use the Audit page with the Trust Check and Policy Decision events selected.

Match the code to its cause

Look the code up in the tables below and make the fix it points to.

The registry answered

CodeWhat it meansWhat to check
NOT_RECOGNIZEDThe registry has no record that the Authority recognises the Entity.That the Authority ID and Entity ID are the DIDs you intend. See Which DID goes in which field. That the agent’s own gateway recorded it: its Identities page shows Recorded.
NOT_AUTHORIZEDThe registry has no record that the Authority authorises the Entity for the Action on the Resource.The Action and Resource values, and the same DIDs as above.

When the DIDs and values are right, these codes are the answer you asked for: the agent is not trusted for that query.

The check did not complete

CodeAudit page showsWhat it meansWhat to check
TRUST_REGISTRY_UNREACHABLEthe trust registry was unreachableThe gateway has no working connection to the registry.Connections › Registries: the registry is CONNECTED. Use Reconnect if it is not.
QUERY_TIMEOUT, QUERY_FAILEDQUERY_TIMEOUT: the registry query timed out
QUERY_FAILED: the registry query failed
The query was sent but no usable answer came back in time.That the registry is running. Try the request again.
TRUST_REGISTRY_PROBLEM_REPORTthe registry returned a problem reportThe registry refused the query. Its own code is in error.message.That code, with the registry’s administrator.
TRUST_REGISTRY_PARSE_ERRORthe registry response could not be parsedThe registry answered in a format the gateway did not expect.The registry’s version, with its administrator.
TEMPLATE_RESOLUTION_FAILED, TRUST_REGISTRY_METADATA_UNAVAILABLETEMPLATE_RESOLUTION_FAILED: a query template could not be resolved
TRUST_REGISTRY_METADATA_UNAVAILABLE, caller leg: the caller’s request payload is missing the trust registry metadata extension
TRUST_REGISTRY_METADATA_UNAVAILABLE, target leg: the target’s agent card is missing the trust registry metadata extension
The query names a value the request does not carry, such as the issuer of an agent identity credential the caller did not present, or an agent DID from a caller that sent no identity.That callers present what the query relies on, or pick a fixed Issuer or Authority as the Authority ID.
AGENT_CARD_UNAVAILABLE, TARGET_AGENT_IDENTITY_UNAVAILABLE, IDENTITY_VP_VERIFICATION_FAILEDAGENT_CARD_UNAVAILABLE: the target’s agent card was unavailable
TARGET_AGENT_IDENTITY_UNAVAILABLE: the target’s agent card carries no agent identity credential
IDENTITY_VP_VERIFICATION_FAILED: the target’s agent identity credential could not be verified
Target leg only: the destination’s agent card, or the identity credential in it, could not be fetched or verified.The destination’s agent card and its agent identity credential.

No code

  • No results at all: no Trust Check ran for this request, for example on a Transit Point without one. A policy that only looks for failures allows the request. See Check a Transit Point’s destination.
  • Every check passed but the request is refused: another rule in the policy denied it. The policy decision: deny log line names the policy and its deny_reason.

For every code and the fields each result carries, see Trust Check result fields.

Confirm

Send the refused request again after each change. For an agent that calls your surface from another gateway, send it to the calling surface, whose managed agent forwards it to yours:

curl -X POST "<CALLER_ENTRY_POINT_URL>" \
  -H "Content-Type: application/json" \
  -H "A2A-Version: 0.3" \
  -d '{"jsonrpc":"2.0","method":"message/send","id":1,"params":{"message":{"messageId":"trust-check-1","role":"user","parts":[{"kind":"text","text":"Hello"}]}}}'

Test 1: request sent again after a configuration fix returns 200

Expected: your managed agent’s response, returned through the calling agent. On the Audit page, the request’s record reads Trust check passed, and its Result is Passed.

Test 2: request from an agent the registry does not trust still returns 403

When the DIDs and values are right but the agent has no matching record, the request stays refused, and that is the intended outcome.

Expected: your surface refuses the forwarded request with 403. The curl output depends on how the calling agent reports the refusal, so check the result on your Audit page: the record reads Trust check failed with “Failed because NOT_RECOGNIZED” or “Failed because NOT_AUTHORIZED”, and no description from the The check did not complete table appears.