Skip to main content

Error Handling

Overview

All Connector NG implementations use a standardized error response format based on RFC 9457 — Problem Details for HTTP APIs. This ensures consistent, machine-actionable, and human-readable error information across all connectors and their upstream systems.

Media type

Error responses use the application/problem+json content type (per RFC 9457 §6.1). The HTTP status code must be 4xx or 5xx.

Content-Type: application/problem+json
note

application/problem+xml is not supported.

Problem object

Each error response body is a JSON object with the following fields:

FieldTypeRequiredDescription
typestringyesA URI reference identifying the problem type. Resolves to a documentation page on this site.
titlestringyesShort, human-readable summary of the problem type (does not change between occurrences).
statusnumberyesHTTP status code. Must match the actual response status code.
detailstringyesHuman-readable explanation specific to this occurrence of the problem.
instancestringnoA URI reference that identifies the specific occurrence (e.g., request path or operation ID).

ILM extensions

In addition to the standard fields, ILM connectors include the following extension properties:

ExtensionTypeRequiredDescription
errorCodestringyesStable error code from the ErrorCode enum (e.g., VALIDATION_FAILED).
timestampstringyesISO 8601 / RFC 3339 timestamp of when the error occurred.
retryablebooleanyesWhether the same request can be safely retried.
correlationIdstringnoTrace identifier from X-Request-Id or W3C Trace Context, used for cross-system correlation.
retryAfterSecondsintegernoBackoff hint in seconds before retrying. Present only when retryable is true (default: 30).

Additional properties

Beyond the fixed extension fields above, ProblemDetailExtended exposes a generic properties map (inherited from Spring's ProblemDetail). Implementations use this map to attach any additional context relevant to the specific error. Per RFC 9457, these entries are serialized as top-level members of the JSON object alongside the standard fields.

A common example is a causes array added for validation errors, where each entry describes one failed field:

Property keyValue typeExample use
causesarray of objectsPer-field validation failures (see VALIDATION_FAILED)

Each causes entry typically contains:

FieldTypeDescription
namestringField or parameter that failed (e.g., csr, subject.commonName)
reasonstringHuman-readable explanation of why it failed
rulestringMachine-readable rule identifier (e.g., PKCS10.DECODE, RFC5280.CN.LENGTH)

Other implementations may add different properties relevant to their error type.

Example

{
"type": "https://docs.otilm.com/problems/common/VALIDATION_FAILED",
"title": "Validation failed",
"status": 422,
"detail": "One or more fields failed validation.",
"instance": "/v1/certificates/requests",
"errorCode": "VALIDATION_FAILED",
"correlationId": "f5a2e0e0c1ec41d4b7208b5b0c7bc7d9",
"timestamp": "2025-09-08T12:41:22Z",
"retryable": true,
"retryAfterSeconds": 30,
"causes": [
{
"name": "csr",
"reason": "PEM is not a valid PKCS#10 CSR (base64 decode failed)",
"rule": "PKCS10.DECODE"
},
{
"name": "subject.commonName",
"reason": "Common Name exceeds 64 characters",
"rule": "RFC5280.CN.LENGTH"
}
]
}

The causes array appears as a top-level property in the JSON because Spring's ProblemDetail flattens the properties map into the response body.

Problem types

Problem type URIs follow the pattern https://docs.otilm.com/problems/{category}/{ERROR_CODE}, where ERROR_CODE is the exact name of the ErrorCode enum value. Each URI resolves to a documentation page with a full description, common causes, and remediation steps.

Common types

These problem types are shared across all ILM services and connectors:

Error codeType URIHTTP StatusRetryableDescription
VALIDATION_FAILED/common/VALIDATION_FAILED422yesOne or more input fields failed validation
RESOURCE_NOT_FOUND/common/RESOURCE_NOT_FOUND404yesThe requested resource does not exist
RESOURCE_ALREADY_EXISTS/common/RESOURCE_ALREADY_EXISTS409yesA resource with the same identifier already exists
BAD_REQUEST/common/BAD_REQUEST400yesMalformed or structurally invalid request
ATTRIBUTES_ERROR/common/ATTRIBUTES_ERROR400yesError processing connector attributes
UNAUTHORIZED/common/UNAUTHORIZED401yesAuthentication credentials missing or invalid
FORBIDDEN/common/FORBIDDEN403yesAuthenticated but not authorized for this operation
REQUEST_TIMEOUT/common/REQUEST_TIMEOUT408yesOperation timed out waiting for upstream response
OPERATION_NOT_SUPPORTED/common/OPERATION_NOT_SUPPORTED501yesOperation is not implemented by this connector
RATE_LIMIT_EXCEEDED/common/RATE_LIMIT_EXCEEDED429yesToo many requests in the allowed time window
SERVICE_UNAVAILABLE/common/SERVICE_UNAVAILABLE503yesService or a critical dependency is temporarily unavailable
INTERNAL_SERVER_ERROR/common/INTERNAL_SERVER_ERROR500noUnexpected server error — report with correlation ID