> For the complete documentation index, see [llms.txt](https://docs.openiam.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openiam.com/administration-guide/reference/reconciliation-situations-and-responses.md).

# Reconciliation situations and responses

The four reconciliation situations, what each of the eleven responses actually writes, and every field and script column on the reconciliation form.

## What this is, and when you need it

Every record a reconciliation examines ends in exactly one of four situations, and the response you set on that situation decides what OpenIAM writes. This page is the catalogue: the four situations, the eleven responses with their real blast radius, the seven of them group reconciliation implements, and the fields and script columns on the form.

Read it before you change any response away from `NOTHING`. The procedure — including the report-only first pass that tells you which situation your records actually land in — is [Configure reconciliation](/administration-guide/lifecycle/configure-reconciliation.md).

## The four situations, and the responses you may set on them

Four situations and eleven responses, both listed with the constants stored behind the labels in [Enumerated values](/administration-guide/reference/enums.md#reconciliation-situations). The situations are:

| Situation                    | Webconsole label                               | What it means                                                                                                | Which pass reaches it |
| ---------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------- |
| `SYS_EXISTS__IDM_NOT_EXISTS` | OpenIAM \[not found] — Target system \[exists] | The target has an account the match rule could not tie to any OpenIAM user. An orphan.                       | target → OpenIAM      |
| `IDM_EXISTS__SYS_EXISTS`     | OpenIAM \[exists] — Target system \[exists]    | Both sides have the object. The attribute values may still differ.                                           | both                  |
| `IDM_EXISTS__SYS_NOT_EXISTS` | OpenIAM \[exists] — Target system \[not found] | OpenIAM holds an identity for this managed system but the target lookup returned nothing. A missing account. | OpenIAM → target      |
| `IDM_DELETED__SYS_EXISTS`    | OpenIAM \[deleted] — Target system \[exists]   | The account is in the target but OpenIAM no longer has an identity for it.                                   | see the note below    |

{% hint style="warning" %}
`IDM_DELETED__SYS_EXISTS` does not behave as its label suggests, and the behaviour differs by object type. On a **user** config the row for this situation is never used: no record ever reaches it, so whatever response you set there has no effect. On a **group** config it is reached on the *target lookup returned nothing* branch — the case a user config reports as `IDM_EXISTS__SYS_NOT_EXISTS`. So on a group config, put your "account missing in the target" response on `IDM_DELETED__SYS_EXISTS`, not on `IDM_EXISTS__SYS_NOT_EXISTS`.

Confirm it on your own build before you rely on it: set all four rows to `NOTHING`, run once, and read the `SITUATION` column of the report CSV. Whichever situation your missing accounts land in is the row whose response matters.
{% endhint %}

All four rows must exist. A missing row does not make OpenIAM skip that situation — it fails the batch of records that hit it with a `NullPointerException`, so a config saved with three rows appears to run and loses records. The Webconsole creates all four when you add a config; check them if the config was created by import or by SQL.

## The eleven responses

Nothing validates a response against a situation. Any response OpenIAM implements can be selected for any situation and will be run there, sensible or not — the combination is your responsibility, and the report CSV from a `NOTHING` run is the only place you can check it before it acts.

| Response              | Webconsole label                         | What it actually does                                                                                                                                                                                                    | Blast radius                                                                                                                                                                                |
| --------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NOTHING`             | Do Nothing                               | Runs the population script and stops. No save, no connector call. The report row is still written.                                                                                                                       | None. This is the report-only response.                                                                                                                                                     |
| `NOTHING_AND_INFORM`  | *no label ships*                         | **Not implemented.** On a user config the part aborts with `INTERRUPTED_EXCEPTION`, "cannot define recon command properly. Please check configuration". On a group config nothing happens at all.                        | Aborts the part (users) or silently skips every record (groups).                                                                                                                            |
| `ADD_TO_IDM`          | Add Record to OpenIAM from Target System | Runs the script; on return `0`, adds a login in the default managed system if the script did not, then `save(ProvisionUser)`.                                                                                            | Wide. Creates OpenIAM users, which then provision onward to every resource their birthright rules grant.                                                                                    |
| `ADD_TO_RES`          | Add Record to Target System from OpenIAM | Runs the script, then `save(ProvisionUser)`.                                                                                                                                                                             | Creates accounts in the target.                                                                                                                                                             |
| `UPDATE_IDM_FROM_RES` | Update OpenIAM from Target System        | Runs the script, then `save(ProvisionUser)`. The script is what copies target values onto the user.                                                                                                                      | Overwrites OpenIAM attributes, and the save re-provisions the user everywhere.                                                                                                              |
| `UPDATE_RES_FROM_IDM` | Update Target System from OpenIAM        | Reloads the user from OpenIAM with `UserCollection.ALL`, sets `reconciliationObject = true`, runs the script against that copy, then saves.                                                                              | Overwrites target attributes. **Users only.**                                                                                                                                               |
| `DISABLE_IN_IDM`      | Deactivate in OpenIAM                    | Sets `active = false` on the `Login` for *this* managed system only, then saves. The user's own status is untouched.                                                                                                     | Narrow — one identity, one managed system. **Users only.**                                                                                                                                  |
| `DISABLE_IN_RES`      | Deactivate in Target System              | **Not implemented for either object type.** Same failure as `NOTHING_AND_INFORM`.                                                                                                                                        | Aborts the part (users) or skips (groups).                                                                                                                                                  |
| `DELETE_FROM_IDM`     | Delete from OpenIAM                      | Adds this managed system's resource to the user's skip-provisioning set and then **saves** — it does not itself delete anything. Only whatever the population script changed is persisted, and the target is not called. | Depends entirely on your script. Misleadingly named.                                                                                                                                        |
| `REMOVE_FROM_IDM`     | Remove from OpenIAM                      | Removes the user — the same operation as a delete request whose status is `REMOVE`. This is the genuinely destructive OpenIAM-side response.                                                                             | Irreversible. On a group config it deletes the group.                                                                                                                                       |
| `DELETE_FROM_RES`     | Delete from Target System                | For an unmatched orphan — a target account with no OpenIAM user behind it — calls the connector's delete directly for that principal. Otherwise marks that managed system's `Login` for deletion and saves.              | Deletes accounts in the target. Combined with `SYS_EXISTS__IDM_NOT_EXISTS` this deletes every account OpenIAM failed to match — including every account your match configuration got wrong. |

Every response except `NOTHING`, and except the orphan branch of `DELETE_FROM_RES`, acts **only if the population script returns `0`**. A return `> 0` logs `Incorrect return code from population groovy script. User <principal> not processed` and does nothing; a negative return throws. That return code is the safest per-record veto you have.

## Group reconciliation supports only seven of the eleven responses

This is not documented anywhere in the product or the UI. Group reconciliation implements exactly seven of the eleven responses: `NOTHING`, `ADD_TO_IDM`, `ADD_TO_RES`, `UPDATE_IDM_FROM_RES`, `DELETE_FROM_IDM`, `REMOVE_FROM_IDM` and `DELETE_FROM_RES`.

**Unavailable for groups: `UPDATE_RES_FROM_IDM`, `DISABLE_IN_IDM`, `DISABLE_IN_RES` and `NOTHING_AND_INFORM.`** For a group equivalent of the four missing responses, write a custom command — see [Custom command scripts](/administration-guide/lifecycle/reconciliation-scripts.md#custom-command-scripts).

{% hint style="danger" %}
The Webconsole offers all eleven anyway — the **Response** dropdown is built from the full list of responses with no filter on object type, so `UPDATE_RES_FROM_IDM` on a group config saves without complaint.

What happens then depends on which situation the record hit. In four of the five places a group record can be acted on, an unimplemented response makes OpenIAM skip the record in complete silence — no audit failure, no log line, no report entry. In the fifth — the `IDM_EXISTS__SYS_EXISTS` situation on the OpenIAM → target pass — each record's child audit entry fails with a `NullPointerException` instead, and if the reconciliation service log is at debug level the whole batch fails.

A group reconciliation that "runs successfully and changes nothing" is almost always this. Check `RECONCILIATION_SITUATION.SITUATION_RESP` against the seven values above before looking anywhere else.
{% endhint %}

## Every field on the reconciliation form

One `RECONCILIATION_CONFIG` row per config, keyed `RECON_CONFIG_ID`. The Webconsole field labels and the columns behind them:

| Field                                     | Column                                 | Notes                                                                                                                                                                                                                                                                                |
| ----------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Active                                    | `ACTIVE` (`Y`/`N`)                     | `preStartChecks` throws `RECON_CONFIG_INACTIVE` if `N`. Also deletes the schedule — see Frequency.                                                                                                                                                                                   |
| Type                                      | `RECON_TYPE`                           | `USER` or `GROUP` (`ReconConfigTypeOptions`). Required — `ReconciliationValidator` rejects a blank. Read-only once the config has an id.                                                                                                                                             |
| Frequency                                 | `FREQUENCY`                            | A cron expression from `CommonFrequencyOptions`: `0 0/5 * * * ?`, `0 0/15 * * * ?`, `0 * 0/1 * * ?`, `0 0 0 * * ?`.                                                                                                                                                                  |
| Manual Reconciliation                     | `MANUAL_RECONCILIATION_FLAG`           | Persisted and round-tripped, but no controller and no service code in this release reads it. Treat it as inert.                                                                                                                                                                      |
| Target system search query filter         | `TARGET_SYS_SEARCH_FILTER` (200 chars) | Passed to the query script as the `searchFilter` binding.                                                                                                                                                                                                                            |
| OpenIAM search query filter               | `SEARCH_FILTER` (200 chars)            | Passed to the OpenIAM search script as `searchFilter`. The shipped scripts parse it as JSON.                                                                                                                                                                                         |
| OpenIAM field name                        | `MATCH_FIELD_NAME` (40)                | `MatchObjectConstant` value: `NAME`, `ATTRIBUTE`, `PRINCIPAL`, `MANAGED_SYS_PRINCIPAL`, `USERID`, `EMAIL`, `EMPLOYEE_ID`. Blank throws `INVALID_ARGUMENTS`.                                                                                                                          |
| Source Attribute Name                     | `CUSTOM_MATCH_SRC_ATTR` (40)           | The **target** attribute holding the value to match on, and the attribute the connector treats as the principal (`searchRequest.setPrincipalAttrName`).                                                                                                                              |
| OpenIAM Custom Attribute Name             | `CUSTOM_MATCH_ATTR` (40)               | Only used when OpenIAM field name is `ATTRIBUTE`.                                                                                                                                                                                                                                    |
| Updated since                             | `UPDATED_SINCE`                        | Passed to both search scripts as `updatedSince`.                                                                                                                                                                                                                                     |
| Email Address for Completion Notification | `NOTIFICATION_EMAIL_ADDRESS` (120)     | If set, `endReconProcess` emails the CSV report as an attachment.                                                                                                                                                                                                                    |
| *(report checkbox)*                       | `DO_NOTHING_REPORT_FLAG`               | Saved and read back, but it changes nothing — the report is written on every completed run whether this is ticked or not. Its label key `openiam.ui.reconciliation.send.report.donothing` has no translation, which is why the checkbox renders as that raw key rather than a label. |
| Last Execution time                       | `LAST_EXEC_TIME`                       | Set when the run finishes, and used to build the report filename.                                                                                                                                                                                                                    |
| —                                         | `EXEC_STATUS`                          | One of `STARTING`, `STARTED`, `STOPPING`, `STOPPED`, `FINISHED`, `FAILED`, stored in upper case. Lowercase forms appear in some API payloads; the column itself always holds the upper-case name, so match on that when you query it.                                                |

## Saving the form creates a batch task

Saving a config with a Frequency and Active set creates or updates a `BATCH_CONFIG` row named `Reconcile=<managed system name>`, with `PARAM1 = <RECON_CONFIG_ID>` and the task script from `org.openiam.batch.reconciliation.script` (shipped value `batch/reconciliation.groovy`). Clearing Frequency **or** unticking Active deletes that batch task. Confirm it under **Administration → Batch Tasks** after saving — the task appearing there is the only sign the schedule took.

The name is keyed on the managed system name alone, so a `USER` config and a `GROUP` config on the same managed system share one task. The second config's Frequency overwrites the cron, but `PARAM1` is only set when the task is created — so the schedule keeps running the config that was saved first. Give the two configs different managed systems, or schedule one and leave the other manual.

## Every script column

Eight columns hold script references. Every one of them is an autocomplete field — you pick a script that is already registered in the Groovy manager, not a path.

| Field label                       | Column                         | Table                      | What uses it, and how                                                                                                                                                                                                                                                                                                                                              |
| --------------------------------- | ------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Target system search query script | `TARGET_SYS_MATCH_SCRIPT_ID`   | `RECONCILIATION_CONFIG`    | Stored, shown on screen, and counted when you ask which configs reference a script — but **no reconciliation run reads it in this build** — put the query script in **Custom Processor Script** instead, and see the warning in [Configure reconciliation](/administration-guide/lifecycle/configure-reconciliation.md#point-the-target-search-at-a-narrow-scope). |
| Custom Processor Script           | `RECON_CUSTOM_PROCESSOR_ID`    | `RECONCILIATION_CONFIG`    | Two different things. If the script declares a class implementing `ReconciliationProcessor`, it replaces the built-in processing for the whole run. Otherwise its body is evaluated to obtain the target search query string.                                                                                                                                      |
| OpenIAM search query script       | `MATCH_SCRIPT_ID`              | `RECONCILIATION_CONFIG`    | Instantiated as an `IDMSearchScript` to build the search for the OpenIAM-side pass. Must be non-blank for user configs or the part fails with `RESULT_INVALID_CONFIGURATION`, "target system match script is not defined for reconciliation config".                                                                                                               |
| Custom rule for matching          | `CUSTOM_IDENT_MATCH_SCRIPT_ID` | `RECONCILIATION_CONFIG`    | When set, your script is instantiated as a `MatchObjectRule` and used instead of the built-in rule for the config's `RECON_TYPE`.                                                                                                                                                                                                                                  |
| Preprocessor Script               | `PRE_PROCESSOR_ID`             | `RECONCILIATION_CONFIG`    | Run as a `PrePostExecutor` once, before the target search is sent.                                                                                                                                                                                                                                                                                                 |
| Postprocessor Script              | `POST_PROCESSOR_ID`            | `RECONCILIATION_CONFIG`    | Run once after the last batch of records and before the report is written.                                                                                                                                                                                                                                                                                         |
| Script                            | `GROOVY_SCRIPT_ID`             | `RECONCILIATION_SITUATION` | The population script for that situation. One per situation row, and all four are instantiated when the run starts — so a compilation error in the script for a situation no record reaches still shows up at the beginning of the run.                                                                                                                            |
| Custom Command                    | `CUSTOM_COMMAND_SCRIPT_ID`     | `RECONCILIATION_SITUATION` | When set, it replaces the built-in behaviour entirely — your script is instantiated as a `ReconciliationObjectCommand` and the **Response you selected is ignored**.                                                                                                                                                                                               |

## Batch and performance properties

Three properties. None of them appears in a shipped properties file, so the defaults below *are* the running values unless your deployment sets them. **You cannot confirm these from the Webconsole** — there is no screen that shows a compiled-in default. Ask whoever owns the deployment whether an override was added, and see the [Installation Guide](/installation/installation.md) for where a property override goes.

| Property                                   | Default | What it sizes                                                                                                                                                                            |
| ------------------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `org.openiam.recon.search.batch.size`      | `250`   | Page size for every paged read a run does — the OpenIAM user or group search, and the login search. Raising it means fewer round trips and larger result payloads.                       |
| `org.openiam.recon.batch.size.user.count`  | `30`    | Records per batch, i.e. per queue message, on a user config. This is the unit of parallelism *and* the unit of failure — an exception while processing a batch affects those 30 records. |
| `org.openiam.recon.batch.size.group.count` | `30`    | The same for group configs.                                                                                                                                                              |

One more that affects the report: `org.openiam.recon.report.not.available` (default `N/A`) is the placeholder written into the CSV for any attribute absent on one side. If your report is full of `N/A` in the target columns, the attribute is missing from the policy map, not from the account.

Separately, the OpenIAM-side match lookups are themselves batched, and not by a property you can set: group, role, resource and organization matching look up 100 candidates at a time, and **user** matching only 10, deliberately, because the user object is heavy enough that 100-row lookups timed out. Neither number is configurable, so a user reconciliation over a large managed system makes ten times as many lookup round trips as a group one of the same size — expect it to be slower and do not read that as a fault.

## Related

* [Configure reconciliation](/administration-guide/lifecycle/configure-reconciliation.md) — the report-only procedure and the run evidence.
* [Reconciliation scripts](/administration-guide/lifecycle/reconciliation-scripts.md) — the population, query, match and command contracts.
* [Enumerated values](/administration-guide/reference/enums.md#reconciliation-situations) — the raw situation and response constants.
* [Build a policy map](/administration-guide/lifecycle/policy-map.md) — the attribute rows a reconciliation asks the connector for.

*Applies to OpenIAM 2026.8.1. Last reviewed 7 August 2026.*


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.openiam.com/administration-guide/reference/reconciliation-situations-and-responses.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
