apache/seatunnel · error · IllegalArgumentException

error handler max_error_ratio must be between 0.0 and 1.0…

Error message

error handler max_error_ratio must be between 0.0 and 1.0, but was %s

What it means

IllegalArgumentException from ErrorHandlerConfigUtil.buildStageConfig when the configured max_error_ratio is outside the legal [0.0, 1.0] range. max_error_ratio is a fraction of rows allowed to fail, so values like 5 or 50 (percent-style) are rejected at config-parse time before the job starts.

Solutions

  1. Express the ratio as a fraction between 0.0 and 1.0 (e.g. 5% → 0.05).
  2. Check both global error-handler config and stage-level overrides for the bad value.
  3. Use max_error_records instead if you want an absolute count rather than a ratio.

Example fix

// before
error-handler { max_error_ratio = 5 }
// after
error-handler { max_error_ratio = 0.05 }
Defensive patterns

Strategy: validation

Validate before calling

double r = config.getDouble("max_error_ratio");
if (r < 0.0 || r > 1.0) throw new IllegalArgumentException("max_error_ratio must be a fraction in [0.0,1.0], got " + r);

Type guard

boolean isValidRatio(Object v) { return v instanceof Number n && n.doubleValue() >= 0.0 && n.doubleValue() <= 1.0; }

Try / catch

try { buildStageConfig(stage, global); } catch (IllegalArgumentException e) { if (e.getMessage().contains("max_error_ratio")) { fixRatioConfig(); } }

Prevention

When it happens

Trigger: Setting env.error-handler.max_error_ratio (globally or per stage) to a negative value or a value > 1.0, e.g. 5 meaning '5%' instead of 0.05.

Common situations: Users writing percentage values (50 instead of 0.5); typo'd decimals like 1.5; copy-pasting configs between systems with different ratio conventions.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/4b7df31775e1b18a. 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:68

            return disabledConfig();
        }

        ReadonlyConfig envConfig = ReadonlyConfig.fromMap(envOptions);
        Map<String, Object> root = envConfig.getSourceMap();

        Map<String, Object> global =
                getNestedMap(root, "error_handler").orElse(Collections.emptyMap());

        String stageKey =
                stageType == StageType.TRANSFORM ? "transform_error_handler" : "sink_error_handler";
        Map<String, Object> stage = getNestedMap(root, stageKey).orElse(Collections.emptyMap());

        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");

View on GitHub (pinned to cf67b549a7)