risingwavelabs/risingwave · error · SinkError::Config

`max_batch_rows` must be between 1 and {}, got {}

Error message

`max_batch_rows` must be between 1 and {}, got {}

What it means

The PostgreSQL sink validates that the `max_batch_rows` sink config option is between 1 and MAX_BATCH_ROWS_LIMIT. `validate()` runs when the sink is created (CREATE SINK). If the user supplied a value outside that inclusive range, the sink refuses to start with this config error.

Source

Thrown at src/connector/src/sink/postgres.rs:234

    fn try_from(param: SinkParam) -> std::result::Result<Self, Self::Error> {
        let schema = param.schema();
        let pk_indices = param.downstream_pk_or_empty();
        let config = PostgresConfig::from_btreemap(param.properties)?;
        PostgresSink::new(config, schema, pk_indices, param.sink_type.is_append_only())
    }
}

impl Sink for PostgresSink {
    type LogSinker = BatchingLogSinker<PostgresSinkWriter>;

    const SINK_NAME: &'static str = POSTGRES_SINK;

    crate::impl_validate_sink_unknown_fields!();

    async fn validate(&self) -> Result<()> {
        if !(1..=MAX_BATCH_ROWS_LIMIT).contains(&self.config.max_batch_rows) {
            return Err(SinkError::Config(anyhow!(
                "`max_batch_rows` must be between 1 and {}, got {}",
                MAX_BATCH_ROWS_LIMIT,
                self.config.max_batch_rows
            )));
        }

        if !self.is_append_only && self.pk_indices.is_empty() {
            return Err(SinkError::Config(anyhow!(
                "Primary key not defined for upsert Postgres sink (please define in `primary_key` field)"
            )));
        }

        ensure_no_foreign_key(&self.config).await?;

        // Verify our sink schema is compatible with Postgres
        {
            let pg_conn = self.config.pg_connection_config();
            let pg_table = PostgresExternalTable::connect(

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Set `max_batch_rows` to a value between 1 and MAX_BATCH_ROWS_LIMIT in the WITH options of CREATE SINK.
  2. Remove the `max_batch_rows` option entirely to fall back to the default batch size.
  3. Check the current limit constant in src/connector/src/sink/postgres.rs before tuning.

Example fix

// before
WITH (connector = 'postgres', max_batch_rows = 0)
// after
WITH (connector = 'postgres', max_batch_rows = 1024)
Defensive patterns

Strategy: validation

Validate before calling

let max_batch_rows: usize = 1024;
assert!((1..=4294967295).contains(&max_batch_rows), "max_batch_rows must be between 1 and MAX_BATCH_ROWS_LIMIT");

Type guard

fn valid_batch_rows(v: i64) -> bool { v >= 1 }

Prevention

When it happens

Trigger: CREATE SINK ... WITH (connector='postgres', max_batch_rows = 0) or max_batch_rows set to a value greater than MAX_BATCH_ROWS_LIMIT; also a negative value.

Common situations: Copy-pasted config with max_batch_rows = 0 (thinking 0 means 'unlimited batching'); typos producing huge numbers; tuning batch size for throughput and overshooting the compile-time limit.

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 risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/660253080d07b47a. Report an issue: GitHub.