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