Skip to content
Registry StackDocsv0.46.0

Registry Evidence errors and problems reference

View as Markdown

Look up a problem response from Registry Evidence (Evidence) and decide what your relying party does next. Evidence returns RFC 9457 problem details as application/problem+json, under the frozen contract problem-contract.yaml.

Every problem body has exactly six members: type, title, status, detail, code, and traceId. type is https://id.registrystack.org/problems/registry-evidence/ followed by the code with each . replaced by /. detail is static, value-free text chosen by the code alone: it never carries a selector, token, source value, or internal failure category.

Every response carries a W3C traceparent header. For a problem response, its trace identifier is the same value as traceId. Evidence accepts a valid inbound trace identifier for correlation or mints one, but does not echo tracestate. The trace identifier is not the internal audit operation identifier. All responses use Cache-Control: no-store.

CodeStatusTitleDetailRecovery
evidence.invalid-request400Evidence request is invalidthe Evidence request is invalidCorrect the request body or headers.
request.selector-invalid400Selector is invalidselector does not match an available request profileRead GET /v1/evidence-definitions and send a selector profile it lists, with values the Source’s inputs schema accepts. No source was contacted.
auth.invalid-credential401Bearer access token is invalidbearer access token validation failedSend one valid Bearer access token. The response carries WWW-Authenticate: Bearer realm="registry-evidence".
evidence.denied403Evidence request is not permittedthe Evidence request is not permittedAsk the operator for a grant that covers the requirement, purpose, and selector profile. The response does not say which condition failed.
resource.not-found404Requested resource was not foundthe requested resource was not foundCheck the route and HTTP method.
format.unsupported406Requested format is not supportedthe requested format is not supportedSend one exact supported Accept value.
evidence.unavailable422Evidence could not be producedevidence could not be produced for this requestDo not infer a cause or retry blindly. Retry only after the request inputs or the source’s records may have changed.
evidence.rate-limited429Evidence request rate is exhaustedthe Evidence request rate is exhaustedWait the one second Retry-After: 1 states, then retry.
source.unavailable503Authoritative source is unavailablethe authoritative source is unavailableRetry with backoff, or contact the source operator. A selector value the Source places in a request path segment it cannot occupy (empty, . or .., or containing /, \, %, or a control character) also answers this problem, and a retry does not help: change the value.
service.unavailable503Service is unavailablethe request could not be servedRetry with backoff, or contact the Evidence operator.

evidence.denied never appears without its audit record: when Evidence cannot append the authorization-refusal audit event, it returns service.unavailable instead. A requirement that does not exist and one you are not authorized for are indistinguishable to you, and so are the reasons behind evidence.unavailable.

The Evidence clients map a problem onto one error kind, so your code catches the kind and reads the problem code from the error’s code. Python raises the exception in the table; Node throws EvidenceClientError with kind set to the first column. The full contract is in the Evidence error contract.

KindProblem codesPython
deniedauth.invalid-credential, evidence.denied, evidence.rate-limitedDeniedError
not-availableevidence.unavailableNotAvailableError
invalid-requestevidence.invalid-request, request.selector-invalid, resource.not-found, format.unsupportedInvalidRequestError
unavailablesource.unavailable, service.unavailableUnavailableError

An HTTP 429 response may set the retry delay (retry_after_seconds in Python, retryAfterSeconds in Node). Classification uses the code, HTTP status, type URI, and trace correlation. The clients discard response-authored title and detail text. A malformed problem, a registered code at the wrong status, or broken correlation becomes protocol.

A valid unknown code follows its HTTP status: 401, 403, and 429 are denied; 422 is not-available; other 4xx responses are invalid-request; 5xx responses are unavailable.

POST /v1/evidence/batch uses the same problem contract for a failure that aborts the whole batch. Inside a successful response, an item that could not be produced is the result evidence-not-available, not the evidence.unavailable problem.

POST /v1/public-check is experimental and uses the same problem shape and codes. It adds no code.

  • evidence.invalid-request (400): the Content-Type is not exactly application/json, the body is larger than the route accepts, the body is not JSON with exactly the string members documentNumber and checkCode, or checkCode is not 24 characters of A to Z and 2 to 7. A lowercase checkCode is accepted: the server uppercases it before the comparison.
  • request.selector-invalid (400): documentNumber does not fit the number format the route accepts, or the Source’s inputs schema refuses it.
  • resource.not-found (404): no certificate matches. A wrong number, a wrong code, and a record with no stored code give the same answer, so a caller cannot tell which part was wrong.
  • source.unavailable (503): the registry could not be read. A documentNumber that passes the selector profile and the inputs schema but that the Source binds to a path segment it cannot occupy (for example a/b or ..) answers the same problem, after the access-attempt audit entry and before any registry request. The check code is compared only after the Source returns a record, so every Source failure before the comparison answers this problem. Retry later.
  • service.unavailable (503): Evidence could not complete the check. Retry later.

Both 400 problems come before any audit write and any registry read.

Registry Evidence API