{"record":{"id":"e36213ddcd84f202","repo":"risingwavelabs/risingwave","slug":"failed-to-create-iceberg-table","errorCode":null,"errorMessage":"Failed to create iceberg table.","messagePattern":"Failed to create iceberg table\\.","errorType":"exception","errorClass":"iceberg::Error (ErrorKind::Unexpected)","httpStatus":null,"severity":"error","filePath":"src/connector/src/connector_common/iceberg/jni_catalog.rs","lineNumber":337,"sourceCode":"\n                let table_metadata = resp.metadata;\n\n                let file_io =\n                    FileIOBuilder::new(Arc::new(OpenDalResolvingStorageFactory::new()))\n                    .with_props(file_io_props.iter())\n                    .build();\n\n                Ok(Table::builder()\n                    .file_io(file_io)\n                    .identifier(TableIdent::new(namespace, creation.name))\n                    .metadata(table_metadata)\n                    .runtime(runtime)\n                    .build())\n            })\n        })\n        .await\n        .map_err(|e| {\n            iceberg::Error::new(\n                iceberg::ErrorKind::Unexpected,\n                \"Failed to create iceberg table.\",\n            )\n            .with_source(e)\n        })?\n    }\n\n    /// Load table from the catalog.\n    async fn load_table(&self, table: &TableIdent) -> iceberg::Result<Table> {\n        let inner = self.inner.clone();\n        let file_io_props = self.file_io_props.clone();\n        let runtime = Runtime::try_current()?;\n        let table = table.clone();\n        execute_blocking_jni(move || {\n            execute_with_jni_env(inner.jvm, |env| {\n                let table_name_str = table.to_string();\n\n                let table_name_jstr = env.new_string(&table_name_str).unwrap();","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/connector_common/iceberg/jni_catalog.rs#L319-L355","documentation":"`JniCatalog::create_table` wraps any failure of the JNI create-table call (Java exception, invalid schema/JSON, catalog rejection, or response parse failure) into an iceberg `Unexpected` error with the message 'Failed to create iceberg table.' and the original error as its source.","triggerScenarios":"Calling create_table on a JNI catalog when the JVM-side create fails: invalid schema JSON sent to Java, namespace does not exist, table already exists, permission denied, or the returned result JSON cannot be parsed.","commonSituations":"CREATE TABLE / CREATE SINK into Iceberg with a schema the Java catalog rejects; table already existing in Glue/Hadoop; missing IAM permissions on the target location; malformed or unsupported column types crossing the JNI boundary.","solutions":["Inspect the wrapped source error to find the Java-side exception.","Verify the table does not already exist in the catalog.","Check that the namespace exists and credentials/IAM allow table creation at the warehouse location.","Confirm the table schema (types, identifiers) is supported by the backend catalog.","Ensure the JNI/JVM environment and classpath are correctly configured."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Validate schema and preconditions before JNI create_table\nfn can_create(catalog_exists: bool, table_exists: bool, schema_json: &str) -> Result<(), String> {\n    if !catalog_exists { return Err(\"namespace does not exist\".into()); }\n    if table_exists { return Err(\"table already exists\".into()); }\n    if serde_json::from_str::<serde_json::Value>(schema_json).is_err() { return Err(\"schema is not valid JSON\".into()); }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match catalog.create_table(&ns, ident, schema).await {\n    Err(e) => {\n        tracing::error!(source = ?e.source(), \"iceberg create_table failed\");\n        // inspect e.source() for Java exception: already-exists vs permissions vs schema\n        Err(e)\n    }\n    Ok(t) => Ok(t),\n}","preventionTips":["Pre-check namespace and table existence before create.","Confirm IAM permissions on the warehouse location.","Validate the table schema against backend-supported types before sending over JNI.","Keep the JVM/JNI environment and classpath correctly configured."],"tags":["iceberg","jni","java","table","create"],"backgroundTag":"upstream-api-error","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}