When a destination rejects a record, Hightouch retries it automatically — during the run and on later runs — until it succeeds or you fix the underlying problem.
Hightouch retries rejected records at two levels, both automatic.During a run. When a destination rejects a record, Hightouch retries it within the same run using exponential backoff, up to a set number of attempts (five by default; some destinations set their own limit). Not every error is retried this way. A request the destination rejects as invalid — for example, a 400, 401, 403, or 422 response — is marked rejected immediately instead of retried. Rate-limited requests (429) get a larger retry budget.On later runs. Hightouch keeps an index of every rejected record, keyed by its primary key. It retries each one on every subsequent run until the record succeeds or drops out of your model’s query results. This layer has no attempt limit, so a record with a persistent problem retries indefinitely until you fix it.
A run that finishes with rejected records completes with errors rather than failing. The run finished and synced the rows it could, but not every row landed. In the run list, this shows as Completed with errors, a warning-level status distinct from a failure. A run is marked Failed only when the whole run errors, such as a query failure, an authentication error, or a destination error that stops it before rows process.So a completed run doesn’t guarantee that every record synced. When you troubleshoot, check both the run status and the rejected-row count in the run’s Results column or the live debugger. Set up alerting to be notified when rows are rejected. The Rejected rows alert fires when a run rejects one or more rows.
Some destinations reject an entire batch when it contains even one invalid record. For those, you can enable split retries.With split retries on, Hightouch splits a rejected batch in half and retries each half separately. If a half still fails, Hightouch splits it again, and repeats until the destination marks each record individually as successful or rejected. Splitting stops after a set number of rounds.Split retries pinpoint which records are rejected and why, and they keep valid records from being re-sent alongside invalid ones. Records still rejected at the end of the process are retried on the next run.To turn them on, set Would you like to enable split retries? to Yes in the sync configuration. To check whether a destination supports split retries, see its documentation.
Split retries can lengthen sync times, because a failing batch is retried in
progressively smaller pieces.
If a record holds data the destination won’t accept — a malformed email, a value that breaks a destination rule — Hightouch retries it every run and it keeps getting rejected. Fix the data at the source: edit your model to correct the value or filter the row out of the query results. What counts as valid depends on the destination.
If you set delete behavior to clear or delete removed records, Hightouch sends a clear or delete request when a row leaves your model’s query results. If that request fails — the destination rejects it, or its API is unavailable — Hightouch retries it on the next run.To stop retrying a removed row, choose one option:
Set delete behavior to Do nothing. This applies to every removed row, not only the one being retried.
Temporarily set delete behavior to Do nothing, run the sync manually once to clear the removed rows from the CDC diff, then set delete behavior back.
The last two options skip data. During the Do nothing run, Hightouch
doesn’t sync any rows CDC marks as removed. A reset-CDC run doesn’t sync any
model changes — added, changed, or removed rows — made since the previous run.
To reduce the risk of missing changes, run a normal sync right before you use
either option.
A failed run means the run errored as a whole, not that individual records were rejected. Open the run in the live debugger to see the error, then look it up in error codes for the cause and fix.