apache/beam · error · IllegalArgumentException

Decimal precision must be in [1, 76], got

Error message

Decimal precision must be in [1, 76], got 

What it means

Thrown by TableSchema.ColumnType.decimal(int, int) when the requested Decimal precision is outside the ClickHouse-supported range [1, 76]. ClickHouse Decimals allow 1-76 total digits; a companion check further restricts scale to [0, precision].

Solutions

  1. Validate precision to [1, 76] (and scale to [0, precision]) before constructing the ColumnType.
  2. Cap oversized precisions at 76, accepting possible loss of significance, or use Float64.
  3. Fix DDL translation logic to map source precisions into the ClickHouse-valid range.
  4. Check config defaults so unset precision doesn't arrive as 0 or negative.

Example fix

// before
ColumnType t = TableSchema.ColumnType.decimal(100, 10); // precision > 76
// after
int p = Math.min(76, Math.max(1, srcPrecision));
int s = Math.min(p, Math.max(0, srcScale));
ColumnType t = TableSchema.ColumnType.decimal(p, s);
Defensive patterns

Strategy: validation

Validate before calling

int validDecimalPrecision(int precision) {
  if (precision < 1 || precision > 76) {
    throw new IllegalArgumentException("Decimal precision must be in [1, 76]: " + precision);
  }
  return precision;
}
// call: TableSchema.ColumnType.decimal(validDecimalPrecision(p), scale)

Try / catch

try {
  ColumnType t = TableSchema.ColumnType.decimal(precision, scale);
} catch (IllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("precision must be in [1, 76]")) {
    throw new SchemaMappingException("Source Decimal precision " + precision + " exceeds ClickHouse's 76-digit limit");
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling ColumnType.decimal(precision, scale) with precision < 1 or > 76 — e.g. decimal(0,0), decimal(100,5), or precision parsed from a non-ClickHouse DDL like DECIMAL(100,10).

Common situations: Translating MySQL/Postgres DECIMAL definitions whose precision exceeds 76 digits; zero/negative sentinel defaults from missing config; regex DDL parsing grabbing wrong digits.

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/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/faf0b8fccb0d12d3. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/clickhouse/src/main/java/org/apache/beam/sdk/io/clickhouse/TableSchema.java:346

    public static final int DEFAULT_DECIMAL_PRECISION = 10;

    /** Default {@code Decimal} scale in ClickHouse when none is specified. */
    public static final int DEFAULT_DECIMAL_SCALE = 0;

    /**
     * Returns a {@code Decimal(precision, scale)} type.
     *
     * <p>ClickHouse stores {@code Decimal} values as integers of a width chosen from the declared
     * precision: 32 bits for precision 1–9, 64 for 10–18, 128 for 19–38 and 256 for 39–76. The
     * width aliases {@code Decimal32(S)}, {@code Decimal64(S)}, {@code Decimal128(S)} and {@code
     * Decimal256(S)} correspond to precisions 9, 18, 38 and 76.
     *
     * @param precision total number of decimal digits, in {@code [1, 76]}
     * @param scale number of fractional decimal digits, in {@code [0, precision]}
     */
    public static ColumnType decimal(int precision, int scale) {
      if (precision < 1 || precision > 76) {
        throw new IllegalArgumentException(
            "Decimal precision must be in [1, 76], got " + precision);
      }
      if (scale < 0 || scale > precision) {
        throw new IllegalArgumentException(
            "Decimal scale must be in [0, " + precision + "], got " + scale);
      }
      return ColumnType.builder()
          .typeName(TypeName.DECIMAL)
          .nullable(false)
          .precision(precision)
          .scale(scale)
          .build();
    }

    public static ColumnType enum8(Map<String, Integer> enumValues) {
      return ColumnType.builder()
          .typeName(TypeName.ENUM8)
          .nullable(false)

View on GitHub (pinned to 12126d8942)