risingwavelabs/risingwave · error · iceberg::Error (ErrorKind::Unexpected)
Failed to check iceberg table exists.
Error message
Failed to check iceberg table exists.
What it means
JniCatalog::table_exists wraps failures from the JNI existence-check call into this Unexpected iceberg error with the underlying error attached. This is not a 'table does not exist' result — that returns Ok(false); this error means the check itself failed.
Source
Thrown at src/connector/src/connector_common/iceberg/jni_catalog.rs:467
execute_blocking_jni(move || {
execute_with_jni_env(inner.jvm, |env| {
let table_name_str = table.to_string();
let table_name_jstr = env.new_string(&table_name_str).unwrap();
let exists =
call_method!(env, inner.java_catalog.as_obj(), {boolean tableExists(String)},
&table_name_jstr)
.with_context(|| {
format!("Failed to check iceberg table exists: {table_name_str}")
})?;
Ok(exists)
})
})
.await
.map_err(|e| {
iceberg::Error::new(
iceberg::ErrorKind::Unexpected,
"Failed to check iceberg table exists.",
)
.with_source(e)
})
}
/// Rename a table in the catalog.
async fn rename_table(&self, _src: &TableIdent, _dest: &TableIdent) -> iceberg::Result<()> {
todo!()
}
/// Update a table to the catalog.
async fn update_table(&self, mut commit: TableCommit) -> iceberg::Result<Table> {
let inner = self.inner.clone();
let file_io_props = self.file_io_props.clone();
let runtime = Runtime::try_current()?;
execute_blocking_jni(move || {View on GitHub (pinned to 6469eb736d)
Solutions
- Read the with_source error chain for the actual Java exception
- Validate the TableIdent (namespace + table name) matches what exists in the backend
- Check JVM initialization and classpath
- Retry on transient backend connectivity failures
Defensive patterns
Strategy: retry
Validate before calling
// Validate identifier before existence probe debug_assert!(!ident.name().is_empty(), "table name required");
Type guard
fn is_jni_exists_failure(err: &iceberg::Error) -> bool {
err.kind() == iceberg::ErrorKind::Unexpected && err.message().contains("Failed to check iceberg table exists.")
} Try / catch
let exists = loop {
match catalog.table_exists(&ident).await {
Ok(v) => break v,
Err(e) if is_transient(&e) => continue, // backoff
Err(e) => return Err(e),
}
}; Prevention
- Retry existence checks on transient backend errors
- Validate TableIdent format before the JNI call
- Ensure JVM health-checks run before catalog operations
When it happens
Trigger: The JNI/Java catalog tableExists call errors out inside the block_in_place task: Java exception (auth, connectivity, invalid identifier), JNIEnv failure, or a JoinError from a panicked closure.
Common situations: Backend catalog temporarily unreachable during existence probes; malformed TableIdent rejected by the Java catalog; JVM/classpath misconfiguration when RisingWave validates an Iceberg table reference.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Failed to list iceberg namespaces.
- Failed to load iceberg table.
- Failed to drop iceberg table.
- register_table is not supported by JniCatalog
- Failed to update iceberg table.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/282df942b124d8f4.
Report an issue: GitHub.