risingwavelabs/risingwave · error · iceberg::Error (ErrorKind::FeatureUnsupported)
Loading uncommitted table is not supported!
Error message
Loading uncommitted table is not supported!
What it means
After creating a table through the JNI catalog, `JniCatalog::create_table` deserializes a `LoadTableResponse` from the Java side. The response must include `metadata_location`; if it is `None`, the table exists but was never committed (no metadata location), so the code raises an iceberg `FeatureUnsupported` error because loading uncommitted tables is not supported.
Source
Thrown at src/connector/src/connector_common/iceberg/jni_catalog.rs:314
let namespace_jstr = env.new_string(&namespace_str).unwrap();
let creation_str = serde_json::to_string(&CreateTableRequest::from(&creation))?;
let creation_jstr = env.new_string(&creation_str).unwrap();
let result_json =
call_method!(env, inner.java_catalog.as_obj(), {String createTable(String, String)},
&namespace_jstr, &creation_jstr)
.with_context(|| {
format!("Failed to create iceberg table: {}", creation.name)
})?;
let rust_json_str = jobj_to_str(env, result_json)?;
let resp: LoadTableResponse = serde_json::from_str(&rust_json_str)?;
let _metadata_location = resp.metadata_location.ok_or_else(|| {
iceberg::Error::new(
iceberg::ErrorKind::FeatureUnsupported,
"Loading uncommitted table is not supported!",
)
})?;
let table_metadata = resp.metadata;
let file_io =
FileIOBuilder::new(Arc::new(OpenDalResolvingStorageFactory::new()))
.with_props(file_io_props.iter())
.build();
Ok(Table::builder()
.file_io(file_io)
.identifier(TableIdent::new(namespace, creation.name))
.metadata(table_metadata)
.runtime(runtime)
.build())View on GitHub (pinned to 6469eb736d)
Solutions
- Drop the leftover uncommitted table in the catalog backend and recreate it.
- Retry CREATE after cleaning up the stale table entry.
- Check the Java catalog logs to see why the table creation did not commit a metadata location.
- Use a catalog backend whose create flow always commits metadata before responding.
Defensive patterns
Strategy: validation
Validate before calling
// Before create, check the table doesn't already exist as an uncommitted leftover
if catalog.table_exists(&ident).await? {
return Err(format!("table {:?} already exists; drop the stale entry first", ident));
} Try / catch
match catalog.create_table(&ns, ident, schema).await {
Err(e) if e.message().contains("uncommitted") => {
// drop the stale/uncommitted table in the backend, then retry once
}
other => other?,
} Prevention
- Clean up partially-created tables after failed CREATE operations.
- Avoid concurrent creation of the same table; serialize DDL.
- Check table existence before create for idempotent pipelines.
When it happens
Trigger: create_table on a JNI catalog where the Java catalog returns a LoadTableResponse without `metadata_location` — e.g. a table that was created but whose creation transaction never committed, or a staged/uncommitted table response.
Common situations: A leftover partially-created table from a previous failed CREATE operation; concurrent creation where the response reflects a staged table; catalog backends that return staged responses instead of erroring.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Failed to create iceberg table.
- Failed to list iceberg namespaces.
- Failed to create namespace.
- not yet implemented
- Failed to check namespace exists.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/600a694a6f9a5846.
Report an issue: GitHub.