> For the complete documentation index, see [llms.txt](https://docs.empe.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.empe.io/develop/issuer/error-handling-and-troubleshooting.md).

# Error Handling and Troubleshooting

The Issuer Service uses standard HTTP status codes and JSON error responses. A global error filter normalizes every failure into a consistent JSON body, so clients can rely on the same shape across all endpoints.

**Common Status Codes**:

* **400 Bad Request**: Invalid request parameters or missing fields (for example, a credential schema whose `name` contains spaces, or a credential offer with an empty `credentialConfigurationIds` array). The global validation pipe also rejects any JSON property that is not part of the endpoint's schema, with a message like `property X should not exist`.
* **401 Unauthorized**: A missing, malformed, or expired OIDC JWT Bearer token, or a token whose signature cannot be verified against the configured JWKS endpoint.
* **403 Forbidden**: The token is valid but lacks the required `admin` role (accepted from `realm_access.roles` or a `resource_access` client-role entry) on a route that enforces it, or it does not grant ownership of the requested holder.
* **404 Not Found**: A non-existent schema ID (`GET /schemas/:schemaId`) or a request for a hosted DID document that does not exist. Unknown issuer, session, or credential-offer identifiers currently surface as `500` rather than `404`.
* **409 Conflict**: A schema with the same `name` and `version` already exists (`POST /schemas`).
* **410 Gone**: The requested schema version has been superseded by a newer version. Retrieve it by passing `includeInactive=true` on the schema endpoint.
* **429 Too Many Requests**: The global rate limit (60 requests per 60 seconds) has been exceeded. DID document serving is exempt from this limit.
* **500 Internal Server Error**: Unexpected server issues.

**Example Error Response**:

```json
{
  "statusCode": 410,
  "message": "Schema version is superseded.",
  "error": "Gone",
  "path": "/schemas/EmployeeBadge@1.0",
  "timestamp": "2026-06-22T10:15:30.000Z"
}
```

Error bodies always include `statusCode`, `message`, `path`, and `timestamp`; responses produced by standard HTTP exceptions additionally include an `error` label (for example, `"Gone"` for 410 or `"Conflict"` for 409).

**Troubleshooting Tips**:

* Validate request payloads against your credential schema definitions before sending. For SD-JWT credentials, ensure the `vct` claim is present in the signing payload.
* Ensure the request carries a current, unexpired OIDC JWT Bearer token in the `Authorization: Bearer <token>` header. The `admin` role is required only on the agent/DID/issuer/verifier/holder management routes (`/agent/*`) and the cloud-wallet routes (`/holders/:holderId/*`).
* For `401` errors, confirm the JWKS endpoint (`OIDC_JWKS_URL`) is reachable, that the token's `kid` header matches a key published by that endpoint, and that the token has not expired.
* For `403` errors on a management or holder route, confirm the token includes the `admin` role in `realm_access.roles` or in a `resource_access` client-role entry, and that the holder you are addressing belongs to the authenticated user.
* For `410` errors, the schema version is superseded. Use `includeInactive=true` to read the old version, or reference the current active version returned by `GET /schemas/:schemaName/versions`.
* Verify database connectivity (`DATABASE_URL`) — the service stores schemas, sessions, signing keys, and hosted DID documents in PostgreSQL.
* Check service logs for detailed error messages. Server-side failures (`5xx`) are logged with a stack trace; client errors (`4xx`) are logged as warnings.

If issues persist, review your environment configuration (`DATABASE_URL`, `ISSUER_BASE_URL`, `OIDC_JWKS_URL`), your schema definitions, and network connectivity between the service and its OIDC provider.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.empe.io/develop/issuer/error-handling-and-troubleshooting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
