{"record":{"id":"fcd57306f267b1ac","repo":"risingwavelabs/risingwave","slug":"enable-pk-index-requires-an-iceberg-table-with-f","errorCode":null,"errorMessage":"`enable_pk_index` requires an Iceberg table with format version >= 2, but the target table is format version {}","messagePattern":"`enable_pk_index` requires an Iceberg table with format version >= 2, but the target table is format version (.+?)","errorType":"validation","errorClass":"SinkError::Config","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/iceberg/create_table.rs","lineNumber":78,"sourceCode":"}\n\npub async fn create_and_validate_table_impl(\n    config: &IcebergConfig,\n    param: &SinkParam,\n) -> Result<Table> {\n    if config.create_table_if_not_exists {\n        create_table_if_not_exists_impl(config, param).await?;\n    }\n\n    let table = config\n        .load_table()\n        .await\n        .map_err(|err| SinkError::Iceberg(anyhow!(err)))?;\n\n    if config.enable_pk_index {\n        let table_format_version = table.metadata().format_version();\n        if table_format_version < FormatVersion::V2 {\n            return Err(SinkError::Config(anyhow!(\n                \"`enable_pk_index` requires an Iceberg table with format version >= 2, \\\n                 but the target table is format version {}\",\n                table_format_version\n            )));\n        }\n    }\n\n    let sink_schema = param.schema();\n    let iceberg_arrow_schema = schema_to_arrow_schema(table.metadata().current_schema())\n        .map_err(|err| SinkError::Iceberg(anyhow!(err)))?;\n\n    try_matches_arrow_schema(&sink_schema, &iceberg_arrow_schema)\n        .map_err(|err| SinkError::Iceberg(anyhow!(err)))?;\n\n    Ok(table)\n}\n\n/// Returns `true` if this call created the table, `false` if it already existed.","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/iceberg/create_table.rs#L60-L96","documentation":"When `enable_pk_index` is set, `create_and_validate_table_impl` requires the target Iceberg table to use format version >= 2, because the PK index feature relies on v2 metadata (e.g. sequence numbers/row lineage prerequisites). Tables at v1 are rejected with this explicit message.","triggerScenarios":"Creating an Iceberg sink with `enable_pk_index = true` whose loaded table's `metadata().format_version()` is `V1`.","commonSituations":"Old tables created years ago at format version 1 being reused for a new sink; warehouse defaults producing v1 tables; configs enabling pk_index without checking table format.","solutions":["Recreate the target Iceberg table at format version 2 (or later).","Or set the table's format-version property (e.g. `format-version=2` when creating via Spark/Flink/iceberg-rust).","Or disable `enable_pk_index` if v1 compatibility matters more.","Check the existing table's metadata before enabling the option."],"exampleFix":"-- before (Spark DDL of target table)\nCREATE TABLE catalog.db.events (...) TBLPROPERTIES ('format-version'='1');\n-- after\nCREATE TABLE catalog.db.events (...) TBLPROPERTIES ('format-version'='2');","handlingStrategy":"validation","validationCode":"let fv = table.metadata().format_version();\nif enable_pk_index && fv < FormatVersion::V2 {\n    return Err(format!(\"enable_pk_index needs format >= 2, table is {fv:?}\"));\n}","typeGuard":"fn pk_index_supported(fv: FormatVersion) -> bool { fv >= FormatVersion::V2 }","tryCatchPattern":null,"preventionTips":["Create target tables with format-version=2+","Check table metadata before enabling enable_pk_index","Migrate legacy v1 tables instead of reusing them"],"tags":["iceberg","config","format-version"],"backgroundTag":"invalid-config-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}