risingwavelabs/risingwave · error · SinkError::Iceberg
failed to add partition columns
Error message
failed to add partition columns
What it means
After building the partition field descriptors, they are attached to an UnboundPartitionSpec via add_partition_fields. If the iceberg crate rejects any field (invalid transform for the source type, duplicate names/ids, conflicting field ids), the error is wrapped with this static context message.
Solutions
- Read the chained underlying error to see which partition field was rejected.
- Match the transform to the column type (e.g. use `day` only on date/timestamp columns, `truncate`/`bucket` on appropriate types).
- Fix the partition config in the sink WITH options and recreate the sink.
- Check for duplicate partition column names.
Example fix
// before WITH (connector='iceberg', partition.by='day(user_name)') -- day() on a VARCHAR // after WITH (connector='iceberg', partition.by='truncate(user_name, 10)') -- or partition by a timestamp column: partition.by='day(event_time)'
Defensive patterns
Strategy: validation
Validate before calling
// Check each partition transform is valid for its column type before creating
// e.g. day/month/year only on date/timestamp; truncate/bucket per iceberg rules
for (col, transform) in partition_specs {
if !transform_supports(transform, type_of(col)) {
eprintln!("transform {transform} unsupported for column {col} type");
}
} Try / catch
match result {
Err(e) if e.to_string().contains("failed to add partition columns") => {
// fix transform/column pairing in partition.by, then recreate the sink
}
other => other?,
} Prevention
- Apply temporal transforms only to date/timestamp columns.
- Use truncate/bucket transforms appropriate to the column type.
- Avoid duplicate partition column names (each gets a _p_<name> field).
- Consult Iceberg partition transform rules when writing partition.by.
When it happens
Trigger: create_table_if_not_exists_impl calls UnboundPartitionSpec::builder().with_spec_id(0).add_partition_fields(partition_fields) and it returns Err — typically a transform not applicable to the column's type (e.g. year/month/day on a non-date/timestamp column, bucket on unsupported types) or an invalid field id assignment.
Common situations: Partition transform (year/month/day/hour/truncate/bucket) applied to a column type it doesn't support; partitioning on VARCHAR with a temporal transform; multiple partition fields colliding on generated names (_p_<column>).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Partition source column does not exist in schema
- backfill iceberg pk-index sink delete files failed…
- bounded compaction branch
- bounded compaction head sequence
- bounded compaction is not supported for copy-on-write tasks
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/7a9c5743e48fd42b.
Report an issue: GitHub.
Appendix: source
Thrown at src/connector/src/sink/iceberg/create_table.rs:206
Some(id) => partition_fields.push(
UnboundPartitionField::builder()
.source_id(id)
.transform(transform)
.name(format!("_p_{}", column))
.field_id(PARTITION_DATA_ID_START + i as i32)
.build(),
),
None => bail!(format!(
"Partition source column does not exist in schema: {}",
column
)),
};
}
Some(
UnboundPartitionSpec::builder()
.with_spec_id(0)
.add_partition_fields(partition_fields)
.map_err(|e| SinkError::Iceberg(anyhow!(e)))
.context("failed to add partition columns")?
.build(),
)
}
None => None,
};
let sort_order = match &config.order_key {
Some(order_key) => Some(build_sort_order(order_key, &iceberg_schema)?),
None => None,
};
// Some JNI catalogs extract `format-version` from table properties, while
// native Rust Glue rejects reserved properties before creating metadata.
let properties = if matches!(
config.catalog_kind()?,
IcebergCatalogKind::Glue(IcebergCatalogRuntime::NativeRust)
) {View on GitHub (pinned to 6469eb736d)