> 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/troubleshooting/connectors/synchronization-runs.md).

# Troubleshooting a synchronization run

Triage a synchronization run that failed, did nothing, or did the wrong thing — which of the four start-up gates stopped it, and what evidence each leaves.

| Symptom                                              | Likely cause                                                            | Resolution                                                                                    |
| ---------------------------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| The run does not start, and no records are processed | One of the four start-up gates refused it                               | [Which gate stopped it](#which-gate-stopped-it)                                               |
| The run reports success and nothing was imported     | The source returned no rows, or every row was filtered                  | [It started and processed nothing](#it-started-and-processed-nothing)                         |
| Records were processed and the result is wrong       | Matching, a transformation script, or the policy map                    | [It processed records and did the wrong thing](#it-processed-records-and-did-the-wrong-thing) |
| **Test Connection** fails on the configuration       | The source adapter could not be loaded, or the source could not be read | [Test Connection fails](#test-connection-fails)                                               |

This page is about a **run** — what stopped it and what it left behind. Configuring a synchronization, writing its scripts and understanding how matching works are elsewhere, and the [Related](#related) list points at each.

## Which gate stopped it

A run passes four gates before it reads a single record. They are checked **in this order**, and each sets its own response code, so the code tells you how far the run got.

{% stepper %}
{% step %}
**Is the configuration active?** An inactive configuration stops here with `SYNC_CONFIG_INACTIVE`, and the audit entry's failure reason reads *"Synchronization config is in 'INACTIVE' status. Stopping."*

Tick **Active** on the configuration. A run scheduled against an inactive configuration fails every time it fires, quietly, which is why a batch task can look like it is running on time and achieving nothing.
{% endstep %}

{% step %}
**Is the same configuration already running?** The overlap guard refuses a second run of the same configuration. You may see either `FAIL_PROCESS_ALREADY_RUNNING` or `SYNC_CONFIG_ALREADY_RUNNING` — the first is what the check returns, the second is what the run throws, and they mean the same thing.

**Do not force a second run.** Lengthen the schedule interval past the worst-case runtime and read the synchronization history to see how long runs actually take.
{% endstep %}

{% step %}
**Does the preprocessor allow it?** If the configuration names a preprocessor script, OpenIAM calls `isValid(config)` and stops the whole run unless it returns `SUCCESS`.

{% hint style="warning" %}
**`FAIL` is `0`.** A script that returns `0` out of batch-task habit aborts the run. Return `SyncConstants.SUCCESS`, which is `1` — see [Pre-processor and post-processor scripts](/administration-guide/reference/synchronization-script-contracts.md#pre-processor-and-post-processor-scripts).

The code is `SYNCHRONIZATION_PRE_SRIPT_FAILURE` — **`SRIPT`, with no `C`**, misspelled in the product. Search for `SRIPT` rather than `SCRIPT`, and quote it as-is in a ticket.
{% endhint %}
{% endstep %}

{% step %}
**Can the source be read?** The run creates a source adapter for the configuration's synchronization source and reads through it. A source type the factory does not recognise yields no adapter at all — see [The connector synchronization source](/troubleshooting/connectors/sync-vs-async-source.md), which covers the retired `CONNECTOR` value specifically.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
**A gate failure is a run-level failure, so there is no per-record report to read.** The run never reached any records. Look at the audit entry for the run and the `synchronization.log`, not at a downloadable report that will not exist.
{% endhint %}

## Test Connection fails

**Test Connection** on the configuration exercises the source adapter without running a synchronization, which makes it the cheapest way to separate a source problem from everything else.

| Code              | What it means                                                                                                                                                    |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLASS_NOT_FOUND` | The adapter class for that synchronization source could not be loaded. The source type is wrong for this deployment, or a custom adapter is not on the classpath |
| `IO_EXCEPTION`    | The adapter loaded and the source could not be read — a missing or unreadable file for CSV, an unreachable database for RDBMS, an unanswering connector          |

Both carry the underlying message as their error text, which is usually more specific than the code.

## It started and processed nothing

The run completed, the history shows it, and nothing changed.

| Check                                             | Where                                                                                                                                             |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Did the source return rows at all?                | The run's audit entry and the row count in the synchronization history                                                                            |
| Were rows read but filtered out?                  | The downloadable report — a filtered row and a failed row look the same in a total                                                                |
| Is the batch size sane?                           | **Records per Batch** ships `1000` and must be greater than zero; a zero or negative value is rejected with `RECORDS_NUMBER_MUST_BE_GREATER_ZERO` |
| Is a validation or transformation script missing? | Both are mandatory; a configuration without them aborts before processing                                                                         |

{% hint style="info" %}
**A run that reports success having imported nothing is the hardest case**, because success is reported per run rather than per expectation. Run against a two- or three-record source you control when you are establishing why — it makes "nothing was read" and "everything was skipped" distinguishable at a glance.
{% endhint %}

## It processed records and did the wrong thing

Records were read and the outcome is wrong. That is a matching, transformation or provisioning problem rather than a run problem, and each has its own page:

* **Matched the wrong identity, or created duplicates** — [How matching and processing work](/administration-guide/lifecycle/synchronize-and-import-data/synchronization-matching-and-processing.md)
* **A field arrived wrong, or a row was skipped** — [Synchronization scripts](/administration-guide/automation/synchronization-scripts.md), whose table covers `TRANSFORMATION_RETURN_SKIP`, rows failing with no message, and scripts whose edits appear not to take
* **Nothing reached the target system** — the connector, not the synchronization: [General connector troubleshooting](/connector-configuration/4-troubleshootingconnector.md)

## The evidence a run leaves

Three places, and they answer different questions.

| Evidence                                                                                                                                                          | Answers                                                                                       |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| **Audit entries** — `SYNCHRONIZATION` for the run, `SYNCHRONIZATION_THREAD` per thread, `SYNCHRONIZATION_RECORD` per record, `SYNCHRONIZATION_ORPHAN` for orphans | Whether the run started, how far it got, and the failure reason for a run-level stop          |
| **The synchronization report**, downloadable from the history                                                                                                     | What happened to each record. Failure rows carry the response code                            |
| **`synchronization.log`** in `/usr/local/openiam/logs`                                                                                                            | Everything the run and its scripts logged, including the reason a script returned what it did |

A run-level failure appears in the first and third only. A per-record failure appears in all three.

## Related

* [The connector synchronization source](/troubleshooting/connectors/sync-vs-async-source.md) — the source values that exist, and the retired one that silently reads nothing
* [Schedule a synchronization](/administration-guide/automation/batch-tasks/schedule-a-synchronization.md) — putting a run on a cron schedule, and what goes wrong with the schedule itself
* [Synchronization scripts](/administration-guide/automation/synchronization-scripts.md) — writing and changing the scripts a run calls
* [Synchronization script contracts](/administration-guide/reference/synchronization-script-contracts.md) — the five scripts, their methods and return codes
* [Synchronization configuration fields](/administration-guide/reference/synchronization-configuration-fields.md) — every field on the configuration, with its column and shipped default
* [Which log answers which question](/administration-guide/operations/which-log-to-read.md) — when the fault may not be the synchronization's at all


---

# 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/troubleshooting/connectors/synchronization-runs.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.
