ai
Failed Sync Retry: Recover Reverse ETL Failures With an AI Agent on Rails
A reverse ETL failed sync retry is safe only when it repeats the same approved version, audience hash and destination, with an idempotency key and a fresh consent check. A Sync Medic agent starts at L3, where on-call approves each retry, and can reach L4 for this bounded case on a customer data platform (CDP). Anything else needs approval.
Rail level: L3 to L4 · Risk: medium · Function: platform operations
By Art Kukharenko · Published · Updated
All AI agent railsWho this is for: platform leads and data engineers who run audience syncs under an approval process. This job is one rail in the vendor-neutral AI agent rails method. Tool behaviour below comes from vendor documentation read on 1 November 2026.
Before: the manual workflow
The manual workflow for a failed sync is an on-call engineer reading logs and deciding whether to press retry. An alert fires, or a marketer notices a low count. The engineer opens the run, guesses whether the error is transient, and re-runs it or forces a full resync. Nobody checks whether the audience has changed since it was approved. Duplicates appear days later as a complaint, or not at all.
Reverse ETL tools already retry a lot of this themselves. So the human question is narrower than it looks: what happens when the built-in retries stop, and does a re-run still match what someone approved?
When is a retry not a new activation?
A retry is not a new activation only when nothing a person approved has changed. The rule has four tests: same approved version, same audience hash, same destination, and consent re-checked. This table turns it into decisions.
Scroll horizontally to see all columns.
| What changed since approval | Treat it as | Who acts |
|---|---|---|
| Nothing, and the error is transient | Bounded retry | Sync Medic, within limits |
| Some people withdrew consent | The same retry with a smaller set | Sync Medic; the removal count is logged |
| People were added, or the hash differs | New activation | A named approver |
| Field mapping or sync mode | Configuration change | Platform on-call, after a proposal |
| Destination or account | New activation | A named approver; the allow-list still applies |
| Retry limit or window exceeded | Stop | Platform on-call |
| Approval expired | New activation | A named approver |
Consent can only shrink a retry. Anything that grows the set voids the approval, because approval binds to a hash of the exact payload. This needs a frozen copy of the approved audience. If the sync recomputes from a live model, you cannot prove the audience is the same, so point it at a versioned snapshot table instead.
Why do retries cause duplicate deliveries?
Retries cause duplicates because the caller often cannot tell whether the first attempt worked. AWS's engineering guidance describes the core case: when a response is lost, the caller does not know the outcome, and a blind retry can repeat the effect 1. Batches make it worse. Airbyte states that it delivers at least once, and that a partly completed chunk may be re-sent on the next attempt 2. Hightouch and Fivetran Activations can both split a rejected batch and retry the parts 34.
In a warehouse, a duplicate is usually a clean-up task. In a destination, it can reach a person. So the destination's operation sets the highest level a retry may run at. The levels below are our recommendation.
Scroll horizontally to see all columns.
| Destination operation | Effect of a repeat | Duplicate risk | Highest level |
|---|---|---|---|
| Add to a list or audience | Membership stays the same | Low | L4 |
| Upsert on a stable external ID | Converges on one record | Low | L4 |
| Event with a destination dedupe key | Discarded inside the window. Meta dedupes on event ID and name within 48 hours 5 | Low inside the window, high after it | L4 inside the window, otherwise L3 |
| Create or insert with no key | A new row each time. Fivetran's function connectors insert new rows when no primary key is set 6 | High | L3, and fix the design |
| Mirror with removals | May remove on stale data. Mirror compares with what was sent, not the destination 7 | Medium | L3 |
| Journey entry or message trigger | A person may be contacted twice | High, and it cannot be undone | L3 at most, or manual |
An idempotency key closes the lost-response gap where the destination supports one. The same key goes on every attempt. AWS says a known token with different parameters should return a validation error, which is what you want if a payload has drifted 1. Stripe's documentation, a useful reference pattern though not a marketing destination, advises against personal data in keys and says keys can be pruned once at least 24 hours old 8. The lesson is general: the retry window must be shorter than the destination's key or dedupe window.
After: the job on rails, step by step
The failed sync job on rails puts a rules engine on the action path and a model on the explanation.
- A failed sync event arrives. Include partial failures. Hightouch ends a run with rejected rows as "Completed with errors", not "Failed" 3, so an alert on failure alone misses them.
- Rules classify the error. Timeouts, 5xx and 429 are transient. Authentication and validation errors are not, as both Hightouch and Fivetran's connector guidance treat them 39. The agent holds no keys, so a 401 goes to on-call.
- Rules compare against the approval. They check approval hash, snapshot hash, destination, mapping version, operation type, retry count and window.
- The consent service runs a fresh check. Withdrawn people drop out of the set, using the same enforcement as a send-time check. The check ID is stored.
- The execution service retries. It reuses the key, backs off with jitter, and honours
Retry-After4. At L3 it waits for on-call to approve. At L4 it proceeds. - Rules reconcile. Accepted counts are compared with the expected set. A mismatch stops further retries.
- The model explains. It writes the likely cause for on-call and proposes a fix for anything that is not a retry. It holds no retry tool.
Promotion from L3 to L4 needs written evidence and the platform lead's sign-off. Replay past failures in a test destination and find no duplicates. Show that a changed hash blocks the retry and that a withdrawal removes the person. Drill the kill switch. Any breach drops the rail back automatically, as the rail levels require.
L4 also expects reversibility, which limits this rail honestly. A retried list add can be removed using the approved sync's rollback reference. A sent message cannot. So on a failed reconciliation, retries stop and the rail falls to L3, and on-call decides on any removal. Destinations that cannot be reversed never run at L4.
What rules do and what the model does
Rules make every retry decision here, and the model only writes the explanation. Error text from a destination is outside input, and it could contain instructions. The Rule of Two says a session should not hold untrusted input, sensitive access and state-changing tools together 10. So the model reads logs without payload data and has no tools that change state. The action path has no model in it, and a hijacked explanation cannot trigger a retry.
Scroll horizontally to see all columns.
| Task | Done by |
|---|---|
| Classify the error | Rules |
| Compare hash, version and destination | Rules |
| Check consent | Consent service |
| Retry, back off, use the key | Execution service |
| Reconcile counts | Rules |
| Explain a likely cause | Model |
| Propose a fix for anything else | Model proposes; platform on-call approves |
The rail card
The rail card below fixes what Sync Medic may do. Retry limits and windows are yours to set, within the dedupe window above.
Scroll horizontally to see all columns.
| Field | Value |
|---|---|
| Job | Diagnose failed syncs, retry an already approved sync within limits, and propose other fixes. |
| Trigger | A failed sync event, including partial failure. |
| Data scope | Sync logs, error codes and the approval record hash. No payload data. |
| Tool scope | Read: sync logs, error codes, approval record, destination status. Propose: a fix for anything other than a retry. Execute: retry the same approved sync version with idempotency and a fresh consent check. |
| Output contract | Failure cause, retry record, or a fix proposal. |
| Gate | No new approval for a bounded retry of the same approved hash. The platform on-call approves any other change. |
| Limits | Retries per sync, backoff, same destination and audience hash only. |
| Ledger | Sync ID, approval hash, retry count, consent-check ID, outcome. |
| Evaluation | Replay of historic failures in a test destination. |
| Owner and kill switch | Platform lead. Disable retries, and failures go to on-call. |
The first sync still belongs to the Audience Sync Steward, with a named approver bound to the segment hash, as in the segmentation walkthrough. Sync Medic only repeats what that approval covered.
What the ledger shows for one run
The ledger entry for one retry shows that nothing approved has changed. This example is illustrative, with invented values and no personal data.
{
"sync_id": "sync_4471",
"rail": "sync-medic@v2",
"level": "L4",
"error_class": "destination_5xx",
"approval_hash": "9f2c...",
"audience_hash": "71de...",
"destination": "ad_platform_a",
"mapping_version": "v12",
"retry": {"count": 2, "limit": 3, "key_ref": "idem_8841"},
"consent_check_id": "cc_7712",
"removed_by_consent": 14,
"reconciliation": "match",
"outcome": "accepted"
}
Three ways it fails, and the control for each
Each failure below is a known pipeline problem, and each control sits outside the model.
Scroll horizontally to see all columns.
| Failure | What it looks like | Control |
|---|---|---|
| Duplicate delivery | A lost response leads to a second send, or a partial batch is re-sent to a keyless endpoint. | Allow L4 only for operations in the safe rows above. Reuse keys. Reconcile after each run. |
| Retry storm | An outage or rate limit gets worse because the tool retries and the agent retries too. AWS's example of five layers with three retries each gives about 243 times the load, so it advises retrying at one point in the stack 11. | Let one layer own retries. Use backoff, jitter and a budget, then stop. |
| A changed audience passed off as a retry | The next scheduled run picks up new rows, or a withdrawal is missed because the check is stale. | Compare hashes against a frozen snapshot. Require a fresh check ID on every attempt. |
Metrics that are honest
Honest retry metrics count harm as well as speed.
- Mean time to recover, from failure to reconciled delivery.
- Duplicate deliveries, target zero. Measure them in seeded replays and through reconciliation, because production duplicates are easy to miss.
- Failed retries, which show whether error classification is right.
- Retries refused by rule, split by reason. A rise may show approvals expiring too fast.
- Audit coverage. Any retry without a complete record is a defect.
How vendor tools compare
Reverse ETL and pipeline tools handle retries well, and their defaults are often all you need. We read these pages on 1 November 2026. They do not address approval binding, which is not their job.
Scroll horizontally to see all columns.
| Tool | Documented retry behaviour | Stated limit | On duplicates |
|---|---|---|---|
| Hightouch | In-run backoff, up to five attempts by default. 400, 401, 403 and 422 are rejected without retry, and 429 gets more attempts. Rejected rows retry on later runs by primary key 3. | No attempt limit across runs; a row stops when it succeeds or leaves the model's results 3 | The retries page is silent |
| Fivetran Activations (formerly Census) | In-run backoff, batch splitting, Retry-After honoured. Rejected records retry on later runs by primary key 4. | No maximum stated 4 | The page is silent; behaviours include Create Only and Mirror 7 |
| Airbyte | Retries and resumes from committed state. An ingestion tool 2. | Retries while progress continues 2 | At least once. Choose a mode with deduplication 2 |
| Fivetran connectors | Connector SDK guidance: retry transient errors, fail when data integrity is at risk 9. An ingestion tool. | Set by your code | Function connectors are expected to be idempotent 6 |
One detail matters for approvals. Hightouch compares current model results with the previous run 12, so a later run may carry new rows alongside the retried ones. As we read it, that is closer to a new run than to a retry of what was approved. A frozen snapshot table avoids the question.
A vendor's retry plus an alert is enough when the destination upserts, the audience has no approval bound to it, and the data is low-risk. Where approval does apply, a script can do everything on the action path, because that path has no model anyway. Add the model only if on-call wants a written diagnosis. PrivyCDP's immutable audit ledger records each AI-assisted action with the human or system actor that authorised it; Sync Medic itself is a method you would build, not a shipped feature. The rule on approval gates still governs anything outside the bounds.
Checklist
- Alerts fire on partial failure as well as failed runs.
- Syncs read a frozen snapshot, versioned by audience hash.
- Rules classify errors, and authentication failures go to on-call.
- Hash, version, destination and mapping are compared before each attempt.
- A fresh consent check runs on every attempt, and it can only shrink the set.
- Each destination operation has a written highest level.
- Keys are reused across attempts and contain no personal data.
- The retry window is shorter than the key or dedupe window.
- One layer owns retries.
- Reconciliation follows every retry, and a mismatch stops the rail.
The wider function is in the platform and data pipeline operations playbook, and the method is on the AI agent rails hub. To write this rail for your team, download the rail card template.
Browse use casesFunction playbooksAgent roster
FAQ
What is a failed sync retry in reverse ETL?
It is a repeat of a data delivery from a warehouse or customer data platform to a destination after an error. Tools retry rejected rows in the same run and on later runs. On a rail, a retry means something stricter: the same approved version, audience hash and destination, with consent re-checked.
How do you avoid duplicates when retrying a sync?
Prefer operations that converge, such as list adds and upserts on a stable ID. Reuse one idempotency key across attempts where the destination supports it, and keep the retry window inside its dedupe window. Reconcile counts after each run. Treat keyless inserts and message triggers as manual decisions, because a repeat may reach a person.
Does a retried sync need a new approval?
Not if nothing approved has changed and limits are met: same version, hash and destination, with a fresh consent check. Consent may remove people, but nobody may be added. A changed audience, mapping or destination is a new decision, so it needs a named approver or platform on-call, depending on the change.
Why re-check consent on a retry?
Consent can change between the first attempt and the retry, and the original check only described that earlier moment. A withdrawal must take effect wherever the data goes next. A retry therefore needs its own check ID in the ledger. The check can remove people from the set but never add them.
Can an AI agent retry a sync on its own?
Only within written bounds, and only after a period at L3 with evidence and owner sign-off. Even then, rules make the decision and an execution service acts. The model writes the explanation and proposes other fixes. Destinations where a repeat cannot be reversed, such as message triggers, stay with a person.
What is the difference between a rejected row and a failed run?
A rejected row is one record a destination refused, while the rest of the run continued. A failed run stopped as a whole, for example on a query or authentication error. Hightouch reports a run with rejected rows as completed with errors. Monitor both, because the partial case is the one alerts tend to miss.
Sources
- AWS Builders' Library, Making retries safe with idempotent APIs
- Airbyte, resumability
- Hightouch, retries
- Fivetran Activations, retry handling
- Meta, handling duplicate Pixel and Conversions API events
- Fivetran, function connectors
- Fivetran Activations, syncs
- Stripe, idempotent requests
- Fivetran Connector SDK, error handling
- Meta, Agents Rule of Two (31 October 2025)
- AWS Builders' Library, Timeouts, retries and backoff with jitter
- Hightouch, syncs overview
This article is general information, not legal advice.
Further reading
- Failed Sync Retry Agent: Sync Medic
- AI Agents for Data Pipeline Operations
- AI Agent Permissions Template Download
- Agent rails
- AI actions to avoid
Published: · Updated:
Editorial dates describe content changes. Confirm current sources before making legal, security or purchasing decisions.