risingwavelabs/risingwave · error · iceberg::Error (ErrorKind::Unexpected)
Failed to drop iceberg table.
Error message
Failed to drop iceberg table.
What it means
JniCatalog::drop_table wraps any failure from the JNI drop-table operation (Java exception or join error on the block_in_place task) into this Unexpected iceberg error with the original error attached as source. The table was not confirmed dropped.
Source
Thrown at src/connector/src/connector_common/iceberg/jni_catalog.rs:420
async fn drop_table(&self, table: &TableIdent) -> iceberg::Result<()> {
let inner = self.inner.clone();
let table = table.to_owned();
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();
call_method!(env, inner.java_catalog.as_obj(), {boolean dropTable(String)},
&table_name_jstr)
.with_context(|| format!("Failed to drop iceberg table: {table_name_str}"))?;
Ok(())
})
})
.await
.map_err(|e| {
iceberg::Error::new(
iceberg::ErrorKind::Unexpected,
"Failed to drop iceberg table.",
)
.with_source(e)
})
}
async fn purge_table(&self, table: &TableIdent) -> iceberg::Result<()> {
let table_info = self.load_table(table).await?;
self.drop_table(table).await?;
iceberg::drop_table_data(&table_info).await
}
async fn register_table(
&self,
_table_ident: &TableIdent,
_metadata_location: String,
) -> iceberg::Result<Table> {View on GitHub (pinned to 6469eb736d)
Solutions
- Check the attached source error for the underlying Java exception
- Confirm the table exists and the catalog credentials have DROP permission
- Verify JVM setup and that the backend catalog is reachable
- Retry the drop if the failure was transient (network/timeout)
- Use catalog-level checks (table_exists) before dropping to rule out not-found semantics
Defensive patterns
Strategy: try-catch
Validate before calling
if !catalog.table_exists(&ident).await? {
return Ok(()); // nothing to drop
} Type guard
fn is_jni_drop_failure(err: &iceberg::Error) -> bool {
err.kind() == iceberg::ErrorKind::Unexpected && err.message().contains("Failed to drop iceberg table.")
} Try / catch
if let Err(e) = catalog.drop_table(&ident).await {
if e.message().contains("Failed to drop iceberg table.") {
// check source for Java exception; retry if transient
tracing::error!(source = ?e.source(), "drop failed");
}
} Prevention
- Check table_exists before dropping
- Ensure the catalog identity has DROP privileges on the backend
- Retry drop operations on transient network failures
When it happens
Trigger: The JNI call to drop the table in drop_table (called via purge_table) returns Err: Java-side exception (table does not exist per backend policy, auth failure, connection issue), JNIEnv error, or the spawned task panicked (JoinError).
Common situations: Dropping a table that the Java catalog refuses to drop (e.g. missing or access-denied); JVM/classpath problems; transient backend unavailability when purging Iceberg tables from RisingWave.
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.
- register_table is not supported by JniCatalog
- Failed to check iceberg table exists.
- Failed to update iceberg table.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c0a4a6f1799e3451.
Report an issue: GitHub.