risingwavelabs/risingwave · error · iceberg::Error (ErrorKind::Unexpected)
Failed to list iceberg namespaces.
Error message
Failed to list iceberg namespaces.
What it means
`JniCatalog::list_namespaces` delegates the namespace listing to a JVM catalog via JNI and awaits the result on a Tokio runtime. Any failure of the JNI call, the Java-side request, or the response parsing is wrapped as an iceberg `Unexpected` error with the message 'Failed to list iceberg namespaces.' and the original error attached as source.
Source
Thrown at src/connector/src/connector_common/iceberg/jni_catalog.rs:167
_parent: Option<&NamespaceIdent>,
) -> iceberg::Result<Vec<NamespaceIdent>> {
let inner = self.inner.clone();
execute_blocking_jni(move || {
execute_with_jni_env(inner.jvm, |env| {
let result_json =
call_method!(env, inner.java_catalog.as_obj(), {String listNamespaces()})
.with_context(|| "Failed to list iceberg namespaces".to_owned())?;
let rust_json_str = jobj_to_str(env, result_json)?;
let resp: ListNamespacesResponse = serde_json::from_str(&rust_json_str)?;
Ok(resp.namespaces)
})
})
.await
.map_err(|e| {
iceberg::Error::new(
iceberg::ErrorKind::Unexpected,
"Failed to list iceberg namespaces.",
)
.with_source(e)
})
}
/// Create a new namespace inside the catalog.
async fn create_namespace(
&self,
namespace: &iceberg::NamespaceIdent,
_properties: HashMap<String, String>,
) -> iceberg::Result<iceberg::Namespace> {
let inner = self.inner.clone();
let namespace = namespace.clone();
execute_blocking_jni(move || {
execute_with_jni_env(inner.jvm, |env| {
let namespace_str = namespace_to_string(&namespace);View on GitHub (pinned to 6469eb736d)
Solutions
- Inspect the wrapped source error (`with_source`) for the underlying Java exception.
- Verify catalog credentials, endpoint and region in the connection config.
- Ensure the JVM classpath/JNI runtime is correctly provisioned for the chosen catalog backend.
- Retry once the catalog service is reachable.
Defensive patterns
Strategy: retry
Validate before calling
// Before listing namespaces, probe catalog connectivity (e.g. HTTP HEAD for REST catalogs)
// and verify JVM/JNI classpath is present.
async fn catalog_reachable(endpoint: &str) -> bool {
reqwest::Client::new().head(endpoint).send().await.map(|r| r.status().is_success()).unwrap_or(false)
} Try / catch
// Rust: unwrap the iceberg error chain to log the Java cause
match catalog.list_namespaces(ns).await {
Err(e) if e.kind() == iceberg::ErrorKind::Unexpected => {
tracing::error!(source = ?e.source(), "JNI list_namespaces failed; check catalog service/JVM setup");
// backoff and retry
}
other => other?,
} Prevention
- Pre-flight check catalog endpoint and credentials.
- Ensure the JVM/JNI runtime and backend-specific classes are installed.
- Apply bounded exponential backoff for transient catalog outages.
When it happens
Trigger: Calling list_namespaces on a JNI-backed Iceberg catalog when the JVM call fails (Java exception, IPC failure, malformed response JSON).
Common situations: Iceberg catalog backend (Glue/Hadoop/REST via Java) unreachable or misconfigured; missing JVM/JNI classes on the classpath; authentication failure against the catalog service.
Related errors
- Failed to create namespace.
- Failed to check namespace exists.
- Failed to list iceberg tables.
- Failed to create iceberg table.
- Failed to load iceberg table.
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/053ab26d769df625.
Report an issue: GitHub.