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

  1. Drop the leftover uncommitted table in the catalog backend and recreate it.
  2. Retry CREATE after cleaning up the stale table entry.
  3. Check the Java catalog logs to see why the table creation did not commit a metadata location.
  4. 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

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


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/600a694a6f9a5846. Report an issue: GitHub.