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_schemaView on GitHub (pinned to 6469eb736d)
Solutions
- Adjust the sink query so it selects exactly the same number of columns as the Iceberg table.
- If the Iceberg table changed, recreate the sink to match the new schema.
- 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
- SELECT exactly the table's columns — no subsets, no extras.
- Re-create the sink when the Iceberg table evolves.
- Diff the sink query's projection against the table DDL before deploying.
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
- Field {} not found in our schema
- field {}'s type is incompatible RisingWave converted data ty
- Column order mismatch at position {}: the sink has column `{
- {} unsupported in {} catalog
- Can't find schema by id {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/e53c17266ee7c4e4.
Report an issue: GitHub.