apache/seatunnel · error · OptionValidationException
JDBC XA sink requires max_retries equal to 0 when…
Error message
JDBC XA sink requires max_retries equal to 0 when is_exactly_once=true, otherwise it could cause duplicates.
What it means
JdbcSinkFactory validates option combinations at config-evaluation time. When is_exactly_once=true, the XA transactional sink requires MAX_RETRIES to be 0 because retrying a statement inside an XA transaction can replay already-committed batches, causing duplicate rows. The library throws OptionValidationException during option validation to fail fast at job-creation time.
Solutions
- Set max_retries = 0 in the sink configuration when is_exactly_once = true.
- If retry behavior is needed, disable is_exactly_once and accept at-least-once semantics with idempotent targets (e.g. primary-key upsert).
- Review the sink config block and remove conflicting max_retries overrides from the HOCON/SQL config.
Example fix
// before
sink {
Jdbc {
is_exactly_once = "true"
max_retries = 3
}
}
// after
sink {
Jdbc {
is_exactly_once = "true"
max_retries = 0
}
} Defensive patterns
Strategy: validation
Validate before calling
if (config.getBoolean("is_exactly_once") && config.getInt("max_retries") != 0) {
throw new IllegalArgumentException("max_retries must be 0 when is_exactly_once=true");
} Prevention
- Never set max_retries together with is_exactly_once=true
- Validate sink option combinations in CI before deploying jobs
- Use config templates per delivery-semantics mode (at-least-once vs exactly-once)
When it happens
Trigger: Configuring a JDBC sink with is_exactly_once = true while max_retries is set to any value other than 0; the validator (JdbcSinkFactory option validator evaluate()) is invoked when ReadonlyConfig is validated against the Option definitions.
Common situations: Users enable exactly-once semantics for XA-capable databases (MySQL, PostgreSQL, Oracle, DB2) but keep a max_retries value copied from an at-least-once configuration; upgrading from non-XA to XA sink mode without revisiting retry settings.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- unable to fail/rollback current transaction, xid=
- COMMON_WRITER_OPERATION_FAILED
- COMMON_WRITER_OPERATION_FAILED
- CONFIG_VALIDATION_FAILED
- CONFIG_VALIDATION_FAILED
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/2832aeb1479c962c.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkFactory.java:457
/**
* Submission-time validator for {@code is_exactly_once=true}.
*
* <p>JDBC XA sink does not support retries; {@code max_retries} must be 0 when exactly-once is
* enabled, otherwise duplicates may occur.
*/
static class ExactlyOnceMaxRetriesValidator implements ConditionExtension<Boolean> {
@Override
public String description() {
return "is_exactly_once=true requires max_retries=0";
}
@Override
public boolean evaluate(ReadonlyConfig config, Boolean value)
throws OptionValidationException {
if (Boolean.TRUE.equals(value)) {
int maxRetries = config.get(JdbcSinkOptions.MAX_RETRIES);
if (maxRetries != 0) {
throw new OptionValidationException(
"JDBC XA sink requires max_retries equal to 0 when is_exactly_once=true, "
+ "otherwise it could cause duplicates.");
}
}
return true;
}
}
}
View on GitHub (pinned to cf67b549a7)