risingwavelabs/risingwave · error
System column `{}` is not allowed in order_key
Error message
System column `{}` is not allowed in order_key What it means
`validate_order_key_columns` rejects order key items whose column name starts with an underscore (`_`), since those are RisingWave system/hidden columns that have no counterpart in the Iceberg table schema. Only user-defined columns may be used in the sort order.
Source
Thrown at src/connector/src/sink/iceberg/create_table.rs:572
if order_keys.is_empty() {
bail!("order_key must not be empty");
}
Ok(order_keys)
}
pub fn validate_order_key_columns<'a>(
order_key: &str,
columns: impl IntoIterator<Item = &'a str>,
) -> std::result::Result<Vec<IcebergOrderKeyField>, anyhow::Error> {
let parsed = parse_order_key_exprs(order_key.to_owned())?;
let columns = columns
.into_iter()
.map(|column| column.to_ascii_lowercase())
.collect::<std::collections::HashSet<_>>();
for item in &parsed {
if item.column.starts_with('_') {
bail!(
"System column `{}` is not allowed in order_key",
item.column
);
}
if !columns.contains(&item.column.to_ascii_lowercase()) {
bail!("Order key column does not exist in schema: {}", item.column);
}
}
Ok(parsed)
}
fn build_sort_order(order_key: &str, schema: &iceberg::spec::Schema) -> Result<SortOrder> {
let order_fields = validate_order_key_columns(
order_key,
schema
.as_struct()
.fields()
.iter()View on GitHub (pinned to 6469eb736d)
Solutions
- Replace the system column with a real user-defined column from the sink schema
- Remove the `_`-prefixed item from order_key
- Pick a physical column that exists in the Iceberg table (the next check also verifies existence)
Example fix
// before order_key = '_row_id' // after order_key = 'id'
Defensive patterns
Strategy: validation
Validate before calling
fn uses_system_columns(order_key: &str) -> bool {
order_key.split(',').any(|i| {
i.trim().split_whitespace().next()
.map_or(false, |c| c.starts_with('_'))
})
}
assert!(!uses_system_columns(order_key), "system columns (_*) are not allowed in order_key"); Try / catch
match build_sort_order(order_key, &columns) {
Ok(sort) => sort,
Err(e) if e.to_string().contains("System column") => {
eprintln!("replace _-prefixed column with a user column: {e}");
Default::default()
}
Err(e) => return Err(e),
} Prevention
- Never reference `_`-prefixed columns in sink options; they exist only inside RisingWave
- Cross-check order key names against the sink schema's user-defined columns
- Filter generated keys to columns present in the Iceberg table schema before configuring the sink
When it happens
Trigger: Including a system column such as `_row_id` or `_rw_ts` in the Iceberg sink `order_key` option, e.g. `order_key = '_row_id'` — the check runs after parsing, during `build_sort_order`/sink option construction.
Common situations: Users familiar with RisingWave internal columns trying to sort by them in Iceberg sinks; accidentally prefixing a column with `_`; scripts generating keys from internal metadata.
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
- order_key must not be empty
- iceberg sink: schema evolution not supported; expect schema
- iceberg sink: partition evolution not supported; expect part
- 'copy-on-write' mode is not supported for append-only iceber
- Invalid order key item `{item}`: `NULLS` must be followed by
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/f092d17a845768c6.
Report an issue: GitHub.