risingwavelabs/risingwave · error

Schema length mismatch, risingwave is {}, and iceberg is {}

Error message

Schema length mismatch, risingwave is {}, and iceberg is {}

What it means

`try_matches_arrow_schema` first checks that the RisingWave sink schema and the Iceberg table's arrow schema have the same number of fields, bailing with a length-mismatch message otherwise. The sink writes columns by position, so column counts must be equal.

Source

Thrown at src/connector/src/sink/iceberg/create_table.rs:399

                .to_arrow_field("", our_field_type)
                .map_err(|e| anyhow!(e))?
                .data_type()
                .clone();
            bail!(
                "field {}'s type is incompatible\nRisingWave converted data type: {}\niceberg's data type: {}",
                arrow_field.name(),
                converted_arrow_data_type,
                arrow_field.data_type()
            );
        }
    }
    Ok(true)
}

/// Try to match our schema with iceberg schema.
pub fn try_matches_arrow_schema(rw_schema: &Schema, arrow_schema: &ArrowSchema) -> Result<()> {
    if rw_schema.fields.len() != arrow_schema.fields().len() {
        bail!(
            "Schema length mismatch, risingwave is {}, and iceberg is {}",
            rw_schema.fields.len(),
            arrow_schema.fields.len()
        );
    }

    let mut schema_fields = HashMap::new();
    rw_schema.fields.iter().for_each(|field| {
        let res = schema_fields.insert(field.name.as_str(), &field.data_type);
        // This assert is to make sure there is no duplicate field name in the schema.
        assert!(res.is_none())
    });

    check_compatibility(schema_fields, &arrow_schema.fields)?;

    // The sink writes columns to the Iceberg table by position, so the column order
    // must match. The check above only validates the name set and types.
    for (idx, (rw_field, arrow_field)) in rw_schema

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Adjust the sink query so it selects exactly the same number of columns as the Iceberg table.
  2. If the Iceberg table changed, recreate the sink to match the new schema.
  3. If RW created the table but counts still differ, check that no parallel schema evolution altered the table.

Example fix

// before: table has 3 columns
CREATE SINK s AS SELECT a, b FROM t;
// after
CREATE SINK s AS SELECT a, b, c FROM t;
Defensive patterns

Strategy: validation

Validate before calling

// assert equal column counts before sink creation
assert_eq!(rw_schema.fields.len(), arrow_schema.fields().len(),
    "sink/table column count mismatch");

Prevention

When it happens

Trigger: Called from `create_and_validate_table_impl` (and tests): sink schema has N columns while the resolved Iceberg table arrow schema has M != N columns.

Common situations: Sink created from a query that selects a subset of the Iceberg table's columns; Iceberg table evolved (columns added/dropped) after the sink was created; misconfigured `create_table_if_not_exists` producing a table with different column count.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/e53c17266ee7c4e4. Report an issue: GitHub.