SAP CPI exception subprocess: a practical guide
The exception subprocess is the single most important error-handling construct in SAP Cloud Integration. This step-by-step guide shows when it triggers, how to capture context, classify errors, choose Error End or Escalation End, keep retry working, and turn it into a reusable template. It supports the reliability pillar.

An exception subprocess in SAP Cloud Integration is the catch block of an integration flow. When any step raises an error, control passes to the subprocess, where you log, build an error response, or trigger retry. Ending it with an Error End event marks the message FAILED; an Escalation End event marks it ESCALATED. Build one reusable template and apply it to every iFlow.
What problem does the exception subprocess solve?
Without an exception subprocess, an error in an integration flow either fails silently or returns an unhelpful technical fault. The exception subprocess gives the flow a single, predictable place to decide what happens on error: log it, build a clean response, store the payload, trigger retry, or end with a specific status. It is the foundation of the reliability pillar, and nearly every robust iFlow needs one.
This is a how-to. Follow the steps below to build a reusable template you can drop into any integration flow, so error handling is consistent across every team.
Step 1: Add the exception subprocess to the iFlow
Inside the integration process, add an exception subprocess. It sits alongside the main process and is triggered automatically when any error is raised in that main process. You do not wire it manually to each step; the runtime routes errors to it. One exception subprocess per integration process is the norm.
Step 2: Capture the error context
The first thing the subprocess should do is capture context. Read the error details the runtime exposes, and log, in a structured, consistent way:
- the integration flow name and the step where it failed,
- the error message and type,
- a correlation ID that ties this message to the wider business transaction,
- the relevant business key, such as the document or order number.
Good logging here is what makes monitoring and triage fast. A correlation ID on every error lets you follow one transaction across steps and systems, turning a multi-hour investigation into a lookup.
Step 3: Classify the error
Decide whether the error is recoverable or permanent:
- Recoverable: a timeout, a target briefly unavailable, throttling, a transient lock. The message should be retried.
- Permanent: a schema violation, a business rejection, a missing mandatory field, an authorisation failure. Retrying will fail again.
This classification decides how you end the subprocess, so make it explicit rather than treating all errors the same. A simple way is to inspect the error type or an HTTP status and branch.
Step 4: Choose the ending
Quick answer: Error End marks the message FAILED, Escalation End marks it ESCALATED, and leaving a recoverable error unfinalised lets it RETRY.
The end event sets the final message status:
| Ending | Resulting status | Use for |
|---|---|---|
| Error End event | FAILED | Permanent errors that need a human |
| Escalation End event | ESCALATED | Handled errors you want flagged for monitoring |
| No finalisation (left for retry) | RETRY | Recoverable errors in a JMS or Data Store scenario |
The subtle point: if you want automatic retry, do not finalise the message. For JMS-based retry especially, a subprocess that fully handles the error stops the runtime from retrying. Keep the recoverable path separate from the permanent path, which is why Step 3 matters.
Step 5: Handle the payload
For permanent failures, store the failing payload and its headers so someone can diagnose and, if needed, replay it. For recoverable failures that have exhausted retry, move the payload to a dead-letter destination. The retry and dead-letter mechanics, including attempt tracking with SAPJMSRetries and SAP_DataStoreRetries, are covered in JMS vs Data Store.
Step 6: Return a meaningful response
For synchronous interfaces, do not leak a raw stack trace to the caller. Build a clean error response with a stable error code and a human-readable message, and keep the technical detail in the log. This makes your APIs easier to consume and avoids exposing internal detail.
Step 7: Make it reusable
Do not rebuild error handling per iFlow. Create one standard exception-subprocess template with consistent logging, correlation IDs, classification, endings and payload handling, and reuse it everywhere. A generic error-handling pattern means every integration behaves the same way when things go wrong, which is exactly what operations teams need. Treat changes to this template as control changes under your change process.
Common mistakes to avoid
- Swallowing a recoverable error so retry never fires.
- Ending every error as FAILED, so monitored-but-handled conditions look like outages.
- Logging without a correlation ID, which makes triage slow.
- Storing payloads but never alerting, so dead-letters pile up unseen.
- Returning technical stack traces to external callers.
How do I test the exception subprocess?
Quick answer: deliberately trigger each error class and confirm the status, logging and retry behave as designed.
An exception subprocess you have never tested is a hope, not a control. Build negative test cases that force each path: point a step at an unavailable target to trigger a recoverable error and confirm it ends in RETRY; send a malformed payload to trigger a permanent error and confirm it ends FAILED with a useful log and alert; and confirm the correlation ID appears in the log. Include these in the regression pack you run before every production change, as covered in the gated guide on testing SAP integrations. Testing the unhappy path is the only way to know your error handling works.
How does this scale across many integration flows?
One well-designed exception subprocess is good; a hundred inconsistent ones are a maintenance problem. Scale it by treating the template as a shared asset: version it, document it, and make it the default starting point for every new iFlow. When you improve the template, for example adding a new log field, roll the change through your change process rather than editing a hundred flows by hand. Consistency is what lets an operations team reason about failures across the whole estate instead of learning each interface's quirks.
What should the exception subprocess log?
Log enough to diagnose without logging sensitive data. A good baseline: the integration flow name and failing step, the error type and message, the correlation ID, and the relevant business key such as an order number. Avoid logging full payloads with personal or financial data; if you must retain a payload for replay, store it in a controlled location with appropriate access, not in plain logs. Structured, consistent logging is what makes monitoring and triage fast.
How does it fit change control?
Because the exception subprocess decides what happens on failure, a change to it is a change to a control, not a cosmetic tweak. Turning an Error End into a silent catch, removing an alert, or widening what counts as recoverable all change the reliability behaviour of the interface. Review such changes with the same rigour as any production change, which is the governance point made in the reliability pillar and the gated SAP integration error handling guide.
Which exchange properties and expressions hold the error?
Quick answer: inside the exception subprocess, the caught exception and its message are available through standard Camel properties and simple expressions. Capture them first, before any other step can overwrite the context.
| Item | How to reference it | Use it for |
|---|---|---|
| Error text | The simple expression for exception.message | Log text, alert content, routing on keywords |
| Stack trace | The simple expression for exception.stacktrace | Deep troubleshooting (log carefully) |
| Exception object | The exchange property CamelExceptionCaught | Scripts that read status codes and response bodies |
| Message ID | The property SAP_MessageProcessingLogID | Correlating alerts with the monitor |
For HTTP receiver failures, the exception object exposes the HTTP status code and the target's response body. A short Groovy script can read both and store them as exchange properties, for example an error code and an error text, so that a router can branch on them without further scripting.
Which end event should the subprocess finish with?
Quick answer: the end event decides the final message status, so choose it deliberately. Error End marks the message as failed, Escalation End marks it as escalated, and a normal End Message completes it successfully and returns a response to the sender.
| End event | Resulting status | When to use it |
|---|---|---|
| Error End | Failed | The message could not be processed and someone must know |
| Escalation End | Escalated | A defined business exception that needs attention but is not a technical failure |
| End Message | Completed | You have deliberately handled the error, for example by returning a structured error response to a synchronous caller, and the platform should not treat it as failed |
The most damaging mistake in exception handling is ending with End Message when the data was not actually processed. The monitor shows green, alerts stay silent, and the failure surfaces days later as a business problem. If you use End Message to return a clean error to a caller, make sure you have logged and alerted on the failure first.
A worked scenario: a timeout versus a validation error
Quick answer: the same exception subprocess should treat these two failures completely differently, and classification is what makes that possible.
An iFlow posts journal entries to S/4HANA. In the first case, the call times out. The subprocess captures the context, the classification step recognises a transient error, and the flow ends with Error End so that the JMS sender retries the message with backoff. In the second case, S/4HANA returns an HTTP 400 because a cost centre is blocked. The subprocess captures the status code and response text, classifies it as a business error, writes a short, payload-free entry with the message ID, and ends with Escalation End while notifying the finance data owner. Same flow, same template, two correct outcomes. For the retry side of the first case, see JMS vs Data Store retry.
When is an exception subprocess not enough?
Quick answer: it handles failures inside one integration flow. Cross-flow concerns such as end-to-end correlation, compensation across systems and landscape-wide alerting need design beyond the subprocess.
If a business process spans several flows, a failure in the third flow may require undoing work done by the first. That compensation logic belongs in a deliberate process design, not in a single subprocess. Likewise, alerting policy, ownership and runbooks are organisational decisions the subprocess merely feeds. The error-handling pillar and the gated error-handling guide cover these wider concerns.
Where this fits
The exception subprocess is step one of reliability; retry and monitoring complete the picture. Continue with the reliability pillar, the retry comparison, or monitoring and alerting, or return to the SAP Integration Suite complete guide. For the governance view, the gated playbook on SAP integration error handling explains how to standardise this across an estate.
Key takeaways
- The exception subprocess catches any error raised in the main integration process.
- End with an Error End event to mark the message FAILED, or an Escalation End event to mark it ESCALATED.
- To keep JMS retry working, do not finalise a recoverable error in the subprocess.
- Always log the error, the step and a correlation ID so triage is fast.
- Standardise one reusable exception-subprocess template across all integration flows.
Questions
When does the exception subprocess run?
It runs whenever an error is raised anywhere in the main process of the integration flow, such as a mapping failure, an adapter error or an explicitly raised exception. Control transfers to the subprocess, which decides the outcome.
What is the difference between Error End and Escalation End?
An Error End event ends the message as FAILED, signalling a hard failure. An Escalation End event ends it as ESCALATED, which is used to flag a handled error for monitoring while still treating it as notable. Choose based on whether the error is terminal or a monitored condition.
How do I keep retry working inside an exception subprocess?
For JMS-based retry, the recoverable error must remain unhandled enough that the runtime retries it. If the subprocess fully handles and finalises the message, the retry will not trigger. Separate recoverable handling from permanent handling.
Should every iFlow have an exception subprocess?
Yes. Any production integration flow should decide explicitly what happens on error. A shared template keeps logging, correlation IDs and status handling consistent across teams.
Can I read the error details inside the subprocess?
Yes. The runtime exposes error information you can read and log, such as the error message and the failing step, which you should capture along with a correlation ID so the failure is diagnosable.
Related reading
See what Spanovix would fix in your landscape
Bring your hardest interfaces. In a short working session we show where the agents cut failures, manual work and risk for your teams.
