apache/seatunnel · warning

DECIMAL scale {} exceeds maximum {}, truncating to {}

Error message

DECIMAL scale {} exceeds maximum {}, truncating to {}

What it means

Warning from DuckDBTypeConverter.handleDecimalType: the DECIMAL scale exceeds the dialect's MAX_SCALE, so scale is truncated to MAX_SCALE. Extra fractional digits will be lost (rounded) when data flows through the converted column definition.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/dialect/duckdb/DuckDBTypeConverter.java:211

    private void handleDecimalType(
            PhysicalColumn.PhysicalColumnBuilder builder, BasicTypeDefine typeDefine) {
        long precision =
                typeDefine.getPrecision() != null ? typeDefine.getPrecision() : DEFAULT_PRECISION;
        int scale = typeDefine.getScale() != null ? typeDefine.getScale() : DEFAULT_SCALE;

        if (precision > MAX_PRECISION) {
            log.warn(
                    "DECIMAL precision {} exceeds maximum {}, truncating to {}",
                    precision,
                    MAX_PRECISION,
                    MAX_PRECISION);
            precision = MAX_PRECISION;
        }
        if (scale < 0) {
            log.warn("DECIMAL scale {} is negative, setting to 0", scale);
            scale = 0;
        } else if (scale > MAX_SCALE) {
            log.warn(
                    "DECIMAL scale {} exceeds maximum {}, truncating to {}",
                    scale,
                    MAX_SCALE,
                    MAX_SCALE);
            scale = MAX_SCALE;
        }

        if (scale <= 0) {
            builder.dataType(new DecimalType((int) precision, 0));
        } else {
            builder.dataType(new DecimalType((int) precision, scale));
        }
        builder.columnLength(precision);
        builder.scale(scale);
    }

    @Override
    public BasicTypeDefine reconvert(Column column) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Round/cast the source column to the supported scale: CAST(col AS DECIMAL(p, MAX_SCALE)).
  2. If full precision is required, transport the value as string and handle decimals downstream.
  3. Check the connector's MAX_SCALE constant and use a compatible source schema.
  4. Accept the truncation if the extra digits are insignificant for your use case.

Example fix

// before
SELECT rate FROM fx; -- DECIMAL(30,20)
// after
SELECT CAST(rate AS DECIMAL(30,12)) AS rate FROM fx; -- within dialect MAX_SCALE
Defensive patterns

Strategy: validation

Validate before calling

if (scale > MAX_SCALE) {
  sql = "SELECT CAST(col AS DECIMAL(" + precision + "," + MAX_SCALE + ")) AS col FROM ...";
}

Type guard

boolean isDuckDbSafeScale(DecimalType t) { return t.getScale() <= MAX_SCALE; }

Prevention

When it happens

Trigger: convert called on a BasicTypeDefine with getScale() > MAX_SCALE, e.g. DECIMAL(30,20) when the dialect max scale is lower.

Common situations: High-precision financial data (scale > 12, etc.) synced from sources like MySQL DECIMAL(65,30) or Postgres NUMERIC with large scale into DuckDB.

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/63e085b5638d2952. Report an issue: GitHub.