apache/seatunnel · error · IllegalArgumentException
error handler max_error_records must be non-negative, but…
Error message
error handler max_error_records must be non-negative, but was %s
What it means
IllegalArgumentException from ErrorHandlerConfigUtil.buildStageConfig when max_error_records is negative. The limit is an absolute count of tolerated row-level errors, so only non-negative longs are valid; 0 disables the threshold.
Solutions
- Set max_error_records = 0 to disable the record-count threshold (that is the 'unlimited' equivalent).
- Use a positive limit matching tolerable dirty-row volume.
- Audit global vs stage-level error-handler blocks for stray negative values.
Example fix
// before
error-handler { max_error_records = -1 }
// after
error-handler { max_error_records = 0 } Defensive patterns
Strategy: validation
Validate before calling
long m = config.getLong("max_error_records");
if (m < 0) throw new IllegalArgumentException("max_error_records must be >= 0 (0 disables the threshold)"); Type guard
boolean isNonNegativeLong(Object v) { return v instanceof Number n && n.longValue() >= 0; } Try / catch
try { buildStageConfig(stage, global); } catch (IllegalArgumentException e) { if (e.getMessage().contains("max_error_records")) { fixRecordsConfig(); } } Prevention
- Use 0, not -1, to disable the record-count threshold
- Validate config programmatically before submit
- Avoid template variables that fall back to -1 for unset limits
When it happens
Trigger: Configuring env.error-handler.max_error_records (global or per stage) with a negative number, e.g. -1 intending 'unlimited'.
Common situations: Users using -1 to mean 'no limit' as in other systems; sign typo; templated configs filling in unset variables as -1.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- At least one sink plugin must be configured.
- At least one source plugin must be configured.
- AzureCosmosDB requires uri, endpoint, or connection string…
- Cannot specify both ' ' and root-level ' '.
- checkResult.getMsg()
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0b663ac69533c8fc.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/task/error/ErrorHandlerConfigUtil.java:80
String modeStr = getString(stage, global, "mode", "DISABLE");
ErrorHandlerMode mode = ErrorHandlerMode.fromString(modeStr);
double maxErrorRatio = getDouble(stage, global, "max_error_ratio", 0.0d);
if (maxErrorRatio < 0.0d || maxErrorRatio > 1.0d) {
throw new IllegalArgumentException(
"error handler max_error_ratio must be between 0.0 and 1.0, but was "
+ maxErrorRatio);
}
int maxErrorRatioMinRecords =
getNonNegativeInt(
stage,
global,
"max_error_ratio_min_records",
DEFAULT_MAX_ERROR_RATIO_MIN_RECORDS);
long maxErrorRecords = getLong(stage, global, "max_error_records", 0L);
if (maxErrorRecords < 0L) {
throw new IllegalArgumentException(
"error handler max_error_records must be non-negative, but was "
+ maxErrorRecords);
}
int queueCapacity = getNonNegativeInt(stage, global, "queue_capacity", 10000);
String overflowStr = getString(stage, global, "queue_overflow_policy", "FAIL");
QueueOverflowPolicy overflowPolicy = QueueOverflowPolicy.fromString(overflowStr);
boolean includeStacktrace = getBoolean(stage, global, "include_stacktrace", false);
boolean includeOriginalData = getBoolean(stage, global, "include_original_data", false);
String dataFormatStr = getString(stage, global, "original_data_format", "TEXT");
if (!"TEXT".equalsIgnoreCase(dataFormatStr)) {
throw new IllegalArgumentException(
"Unsupported original_data_format='"
+ dataFormatStr
+ "'. Current version only supports TEXT.");
}View on GitHub (pinned to cf67b549a7)