This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 7856e3bf67f40406bab66b9626b7cf6c25d440aa
Author: Gabriel <[email protected]>
AuthorDate: Sat Oct 10 18:32:58 2026 +0800

    [fix](regression) Backport external and Kerberos fixes to branch-4.1 
(#68150, #66433) (#68869)
    
    Backport #68150 and #66433 to branch-4.1.
    
    Trino startup/query failures and unfinished HDFS Broker Load jobs could
    appear as empty-result mismatches. Kerberized HDFS clients lacked the
    DataNode SASL setting, and the lightweight Kerberos metastore lacked the
    Paimon fixture. Iceberg metadata write failures could expose only a
    self-suppression wrapper.
    
    This backport adds bounded readiness/load checks with failure
    diagnostics, configures HDFS transfer protection, restores the Paimon
    fixture before the Kerberos readiness marker, and reports the root cause
    of failed Iceberg metadata commits.
    
    Branch adaptation: branch-4.1 uses `IcebergMetadataOps`, so the
    root-cause changes are applied to its create-table, schema-update, and
    branch/tag commit paths. Its partition-spec update helper already
    reports root causes. The newer connector implementation is not
    introduced.
    
    Validation:
    - FE Checkstyle passes: `mvn -pl fe-core -am checkstyle:check`.
    - All six changed suites compile with Groovy 4.0.19.
    - Eight local control-flow scenarios pass for Trino readiness/query
    errors and Broker Load completion/cancellation/timeouts.
    - Shell syntax, Kerberos settings isolation, both container role/switch
    combinations, env/config rendering, and rendered XML checks pass.
    - An isolated harness compiles the actual adapted
    create-table/schema-commit methods with stubbed dependencies: the
    original masks the storage failure, while the backport preserves the
    root message, operation context, and exception cause.
    - `git diff --check` passes. Full FE build and external integration runs
    remain pending CI.
    
    Release note: Improved external regression setup and diagnostics;
    Iceberg metadata commit errors now expose the underlying cause.
    
    Co-authored-by: Mingyu Chen (Rayner) <[email protected]>
---
 .../kerberos/entrypoint-hive-master.sh             | 26 ++++++++++++
 .../docker-compose/kerberos/hadoop-hive.env.tpl    |  4 ++
 .../docker-compose/kerberos/kerberos.yaml.tpl      |  6 +++
 .../kerberos/sql/create_paimon_hive_table.hql      | 20 +++++++++
 docker/thirdparties/run-thirdparties-docker.sh     | 47 +++++++++++++++++++++-
 .../datasource/iceberg/IcebergMetadataOps.java     | 16 ++++----
 .../iceberg/test_iceberg_deletion_vector.groovy    | 42 ++++++++++++-------
 .../refactor_storage_param/hdfs_all_test.groovy    |  2 +
 .../tvf/test_s3_tvf_number_range.groovy            | 32 +++++++--------
 .../paimon/test_paimon_hms_catalog.groovy          |  4 +-
 .../hive_on_hms_and_dlf.groovy                     |  4 +-
 .../iceberg_on_hms_and_filesystem_and_dlf.groovy   |  4 +-
 12 files changed, 165 insertions(+), 42 deletions(-)

diff --git 
a/docker/thirdparties/docker-compose/kerberos/entrypoint-hive-master.sh 
b/docker/thirdparties/docker-compose/kerberos/entrypoint-hive-master.sh
index 6735ae7ee40..885a415d996 100644
--- a/docker/thirdparties/docker-compose/kerberos/entrypoint-hive-master.sh
+++ b/docker/thirdparties/docker-compose/kerberos/entrypoint-hive-master.sh
@@ -136,9 +136,35 @@ kdestroy
 
 report_stage "initialize-hive-metastore"
 schematool -dbType derby -initSchema
+# The Paimon table declares no columns, so the metastore itself resolves its
+# schema through the storage handler. The handler class must therefore be on 
the
+# metastore service's own classpath, not merely on the DDL client's.
+if [[ -d /opt/doris/auxlib ]]; then
+    export HIVE_AUX_JARS_PATH=/opt/doris/auxlib
+fi
 start_service hive --service metastore -p "${HMS_PORT}"
 wait_for_port "${HOST}" "${HMS_PORT}" "Hive Metastore"
 
+# Register the Paimon fixture consumed by test_paimon_hms_catalog. This runs
+# before the readiness marker below on purpose: run-thirdparties-docker.sh
+# releases the pipeline on DORIS_KERBEROS_READY, so anything published later
+# would race the suites. A failure here aborts the container (set -e) instead 
of
+# handing out an environment that is silently missing hdfs_db.
+#
+# Both kerberos containers run this entrypoint with the same env switch, but 
the
+# fixture and its mounts (sql/, paimon_data/, auxlib/) belong to kerberos1 
only -
+# its metastore (9583) is the one the suite talks to. Gate on the container 
role,
+# not on the mounts, so a broken mount on kerberos1 still fails loudly.
+if [[ "${enablePaimonHms:-false}" == "true" && "${HOST:-}" == "hadoop-master" 
]]; then
+    report_stage "load-paimon-hms"
+    export KRB5CCNAME=FILE:/tmp/hive-admin.ccache
+    kinit -kt /data/keytabs/hive.keytab "${HIVE_PRINCIPAL}"
+    hdfs dfs -mkdir -p /user/hive/warehouse
+    hdfs dfs -put -f /opt/doris/paimon_data/* /user/hive/warehouse/
+    hive -f /opt/doris/sql/create_paimon_hive_table.hql
+    kdestroy
+fi
+
 touch /tmp/SUCCESS
 echo "Minimal Kerberos HDFS and Hive Metastore environment is ready"
 echo "DORIS_KERBEROS_READY"
diff --git a/docker/thirdparties/docker-compose/kerberos/hadoop-hive.env.tpl 
b/docker/thirdparties/docker-compose/kerberos/hadoop-hive.env.tpl
index 792d0c0491d..ff95e56f1ae 100644
--- a/docker/thirdparties/docker-compose/kerberos/hadoop-hive.env.tpl
+++ b/docker/thirdparties/docker-compose/kerberos/hadoop-hive.env.tpl
@@ -29,3 +29,7 @@ PRESTO_CLIENT_KEYTAB=${PRESTO_CLIENT_KEYTAB}
 HADOOP_CONF_DIR=/opt/doris/conf
 HIVE_CONF_DIR=/opt/doris/conf
 KRB5_CONFIG=/etc/krb5.conf
+# Paimon-on-kerberized-HMS fixture switch. Read from hive-3x_settings.env by
+# start_kerberos() rather than duplicated into kerberos*_settings.env, so that
+# the pipeline keeps patching exactly one file and the two stacks cannot drift.
+enablePaimonHms=${enablePaimonHms}
diff --git a/docker/thirdparties/docker-compose/kerberos/kerberos.yaml.tpl 
b/docker/thirdparties/docker-compose/kerberos/kerberos.yaml.tpl
index d21496516af..8e903ed6d7f 100644
--- a/docker/thirdparties/docker-compose/kerberos/kerberos.yaml.tpl
+++ b/docker/thirdparties/docker-compose/kerberos/kerberos.yaml.tpl
@@ -33,11 +33,17 @@ services:
     <<: *kerberos-service
     container_name: doris-${CONTAINER_UID}-kerberos1
     hostname: hadoop-master
+    # auxlib/sql/paimon_data are mounted on kerberos1 only: 
test_paimon_hms_catalog
+    # is the sole consumer and it talks to this metastore (9583). Leaving 
kerberos2
+    # untouched keeps the second container as light as it was.
     volumes:
       - ./conf/kerberos1:/opt/doris/conf:ro
       - ./conf/kerberos1/krb5.conf:/etc/krb5.conf:ro
       - ./data/kerberos1:/data
       - ./two-kerberos-hives:/keytabs
+      - ./auxlib:/opt/doris/auxlib:ro
+      - ./sql:/opt/doris/sql:ro
+      - ./paimon_data:/opt/doris/paimon_data:ro
     env_file:
       - ./hadoop-hive-1.env
 
diff --git 
a/docker/thirdparties/docker-compose/kerberos/sql/create_paimon_hive_table.hql 
b/docker/thirdparties/docker-compose/kerberos/sql/create_paimon_hive_table.hql
new file mode 100644
index 00000000000..69a6f476286
--- /dev/null
+++ 
b/docker/thirdparties/docker-compose/kerberos/sql/create_paimon_hive_table.hql
@@ -0,0 +1,20 @@
+-- Paimon table registered in the kerberized Hive Metastore, consumed by the
+-- hdfs_kerberos / hdfs_new_kerberos cases of
+-- external_table_p2/paimon/test_paimon_hms_catalog.groovy.
+--
+-- hdfs_db is backed by ../paimon_data, which the entrypoint uploads into HDFS.
+--
+-- The table declares no columns, so the metastore derives them through the
+-- Paimon storage handler (metastore.storage.schema.reader.impl is
+-- SerDeStorageSchemaReader) -- the Paimon jar has to be on the metastore's own
+-- classpath, not just on the classpath of whoever runs this script.
+
+CREATE DATABASE IF NOT EXISTS hdfs_db;
+
+USE hdfs_db;
+
+DROP TABLE IF EXISTS external_test_table;
+
+CREATE EXTERNAL TABLE external_test_table
+    STORED BY 'org.apache.paimon.hive.PaimonStorageHandler'
+LOCATION 'hdfs:///user/hive/warehouse/hdfs_db.db/external_test_table';
diff --git a/docker/thirdparties/run-thirdparties-docker.sh 
b/docker/thirdparties/run-thirdparties-docker.sh
index 63154a15473..14babf73026 100755
--- a/docker/thirdparties/run-thirdparties-docker.sh
+++ b/docker/thirdparties/run-thirdparties-docker.sh
@@ -1574,6 +1574,46 @@ validate_kerberos_container() {
     fi
 }
 
+# Aux jar for the Paimon fixture in the kerberized metastore: the Paimon 
storage
+# handler the metastore loads to derive the fixture table's schema. Same source
+# and same skip-if-present caching the Hive3 stack uses in 
prepare-hive-data.sh.
+download_kerberos_paimon_jars() {
+    local auxlib_dir="$1"
+    local 
url_prefix="https://${s3BucketName}.${s3Endpoint}/regression/docker/hive3";
+    local jars=(
+        paimon-hive-connector-3.1-1.3-SNAPSHOT.jar
+    )
+    local jar
+
+    for jar in "${jars[@]}"; do
+        if [[ -f "${auxlib_dir}/${jar}" ]]; then
+            echo "Reuse cached kerberos aux jar ${jar}"
+            continue
+        fi
+        echo "Download kerberos aux jar ${jar}"
+        curl -sSfL -o "${auxlib_dir}/${jar}" "${url_prefix}/${jar}"
+    done
+}
+
+# enablePaimonHms lives in hive-3x_settings.env, which the pipeline already
+# patches with the real value. Read it from there instead of duplicating the
+# switch into kerberos*_settings.env, where the two copies would drift and one
+# stack would silently lose the fixture. Sourced in a subshell so that hive3's
+# FS_PORT / HMS_PORT cannot leak into the kerberos settings sourced a few lines
+# below.
+resolve_kerberos_paimon_env() {
+    local hive3_settings="${ROOT}/docker-compose/hive/hive-3x_settings.env"
+
+    enablePaimonHms="false"
+    if [[ -f "${hive3_settings}" ]]; then
+        read -r enablePaimonHms < <(
+            . "${hive3_settings}" >/dev/null 2>&1
+            printf '%s\n' "${enablePaimonHms:-false}"
+        )
+    fi
+    export enablePaimonHms
+}
+
 start_kerberos() {
     echo "RUN_KERBEROS"
     local KERBEROS_DIR="${ROOT}/docker-compose/kerberos"
@@ -1588,8 +1628,13 @@ start_kerberos() {
 
     export CONTAINER_UID=${CONTAINER_UID}
     envsubst <"${KERBEROS_DIR}/kerberos.yaml.tpl" 
>"${KERBEROS_DIR}/kerberos.yaml"
+    # auxlib must exist even when the fixture is off: kerberos1 mounts it 
read-only.
     mkdir -p "${KERBEROS_DIR}/conf/kerberos1" "${KERBEROS_DIR}/conf/kerberos2" 
\
-        "${KERBEROS_DIR}/two-kerberos-hives"
+        "${KERBEROS_DIR}/two-kerberos-hives" "${KERBEROS_DIR}/auxlib"
+    resolve_kerberos_paimon_env
+    if [[ "${enablePaimonHms}" == "true" && "${STOP}" -ne 1 ]]; then
+        download_kerberos_paimon_jars "${KERBEROS_DIR}/auxlib"
+    fi
     for i in {1..2}; do
         . "${KERBEROS_DIR}/kerberos${i}_settings.env"
         envsubst <"${KERBEROS_DIR}/hadoop-hive.env.tpl" 
>"${KERBEROS_DIR}/hadoop-hive-${i}.env"
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
index ccc693f4ad2..0e605f9790d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/iceberg/IcebergMetadataOps.java
@@ -345,9 +345,10 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
         try {
             return executeCatalogOperation(() -> 
performCreateTable(createTableInfo));
         } catch (Exception e) {
+            // Metadata writes can be wrapped by a self-suppression error; 
expose the underlying failure.
             throw new DdlException(
-                "Failed to create table: " + createTableInfo.getTableName() + 
", error message is:" + e.getMessage(),
-                    e);
+                    "Failed to create table: " + 
createTableInfo.getTableName() + ", error message is:"
+                        + ExceptionUtils.getRootCauseMessage(e), e);
         }
     }
 
@@ -582,7 +583,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
             } catch (Exception e) {
                 throw new RuntimeException(
                         "Failed to create or replace branch: " + branchName + 
" in table: " + icebergTable.name()
-                                + ", error message is: " + e.getMessage(), e);
+                                + ", error message is: " + 
ExceptionUtils.getRootCauseMessage(e), e);
             }
         }
     }
@@ -650,7 +651,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
             } catch (Exception e) {
                 throw new RuntimeException(
                         "Failed to create or replace tag: " + tagName + " in 
table: " + icebergTable.name()
-                                + ", error message is: " + e.getMessage(), e);
+                                + ", error message is: " + 
ExceptionUtils.getRootCauseMessage(e), e);
             }
         }
     }
@@ -672,7 +673,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
                 } catch (Exception e) {
                     throw new RuntimeException(
                             "Failed to drop tag: " + tagName + " in table: " + 
icebergTable.name()
-                                    + ", error message is: " + e.getMessage(), 
e);
+                                    + ", error message is: " + 
ExceptionUtils.getRootCauseMessage(e), e);
                 }
             }
         }
@@ -695,7 +696,7 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
                 } catch (Exception e) {
                     throw new RuntimeException(
                             "Failed to drop branch: " + branchName + " in 
table: " + icebergTable.name()
-                                    + ", error message is: " + e.getMessage(), 
e);
+                                    + ", error message is: " + 
ExceptionUtils.getRootCauseMessage(e), e);
                 }
             }
         }
@@ -792,7 +793,8 @@ public class IcebergMetadataOps implements 
ExternalMetadataOps {
         try {
             lease.getAuthenticator().execute(commit);
         } catch (Exception e) {
-            throw new UserException(failureMessage + ", error message is: " + 
e.getMessage(), e);
+            // Preserve the storage failure hidden by metadata writer cleanup 
exceptions.
+            throw new UserException(failureMessage + ", error message is: " + 
ExceptionUtils.getRootCauseMessage(e), e);
         }
     }
 
diff --git 
a/regression-test/suites/external_table_p0/iceberg/test_iceberg_deletion_vector.groovy
 
b/regression-test/suites/external_table_p0/iceberg/test_iceberg_deletion_vector.groovy
index 9b06efc8a85..8d513f0c9f5 100644
--- 
a/regression-test/suites/external_table_p0/iceberg/test_iceberg_deletion_vector.groovy
+++ 
b/regression-test/suites/external_table_p0/iceberg/test_iceberg_deletion_vector.groovy
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+import java.util.concurrent.TimeUnit
+
 suite("test_iceberg_deletion_vector", "p0,external,nonConcurrent") {
     String enabled = context.config.otherConfigs.get("enableIcebergTest")
     if (enabled == null || !enabled.equalsIgnoreCase("true")) {
@@ -495,22 +497,34 @@ s3.path-style-access=true
             30
     )
     executeCommand("${dockerCommand} restart ${trinoContainerName}", true, 60)
-    String trinoRows = ""
-    for (int i = 0; i < 12; i++) {
-        Thread.sleep(5000)
-        trinoRows = normalizeExternalRows(executeCommand(
-                "${dockerCommand} exec ${trinoContainerName} trino 
--output-format TSV " +
-                        "--catalog iceberg --schema format_v3 --execute " +
-                        "\"SELECT id, batch, data " +
-                        "FROM dv_delete_matrix_equality_and_dv ORDER BY id\"",
-                false,
-                120
-        ))
-        if (!trinoRows.isEmpty()) {
+    String trinoCommand = "${dockerCommand} exec ${trinoContainerName} trino 
--output-format TSV " +
+            "--catalog iceberg --schema format_v3 --execute "
+    // A running container does not imply a ready coordinator. Retry startup 
separately so a
+    // failed data query cannot be mistaken for a successful query returning 
no rows.
+    long trinoReadyDeadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(300)
+    def readiness = [exitCode: -1, stdout: "", stderr: "Readiness probe has 
not run"]
+    while (System.nanoTime() < trinoReadyDeadline) {
+        readiness = executeCommandWithStatus(trinoCommand + '"SELECT 1"', 10, 
false, false)
+        if (readiness.exitCode == 0 && readiness.stdout.trim() == "1") {
             break
-            }
+        }
+        Thread.sleep(1000)
     }
-    assertEquals(expectedRows, trinoRows)
+    assertTrue(readiness.exitCode == 0 && readiness.stdout.trim() == "1",
+            "Trino did not become ready within 300 seconds. Exit code: 
${readiness.exitCode}\n" +
+                    
"stdout:\n${readiness.stdout}\nstderr:\n${readiness.stderr}")
+
+    def trinoResult = executeCommandWithStatus(
+            trinoCommand + '"SELECT id, batch, data ' +
+                    'FROM dv_delete_matrix_equality_and_dv ORDER BY id"',
+            120
+    )
+    assertEquals(0, trinoResult.exitCode,
+            "Trino comparison query failed. 
stdout:\n${trinoResult.stdout}\nstderr:\n${trinoResult.stderr}")
+    String trinoRows = normalizeExternalRows(trinoResult.stdout)
+    assertEquals(expectedRows, trinoRows,
+            "Trino comparison query returned unexpected rows. " +
+                    
"stdout:\n${trinoResult.stdout}\nstderr:\n${trinoResult.stderr}")
 
     def profileCounterValues = { String profileText, String counterName ->
         def values = []
diff --git 
a/regression-test/suites/external_table_p0/refactor_storage_param/hdfs_all_test.groovy
 
b/regression-test/suites/external_table_p0/refactor_storage_param/hdfs_all_test.groovy
index 25ca5ebf6da..c2a8a8cdec5 100644
--- 
a/regression-test/suites/external_table_p0/refactor_storage_param/hdfs_all_test.groovy
+++ 
b/regression-test/suites/external_table_p0/refactor_storage_param/hdfs_all_test.groovy
@@ -74,9 +74,11 @@ suite("refactor_params_hdfs_all_test", 
"p0,external,kerberos,external_docker,ext
         assert insertResult.get(0).get(0) == 1
     }
 
+    // Explicit client properties must match the DataNode SASL protection to 
allow writes.
     def hdfsNonXmlParams = "\"fs.defaultFS\" = 
\"hdfs://${externalEnvIp}:8520\",\n" +
             "\"dfs.namenode.kerberos.principal\" = 
\"hdfs/[email protected]\",\n" +
             "\"dfs.client.use.datanode.hostname\" = \"true\",\n" +
+            "\"dfs.data.transfer.protection\" = \"authentication\",\n" +
             "\"hadoop.security.token.service.use_ip\" = \"false\",\n" +
             "\"hadoop.kerberos.min.seconds.before.relogin\" = \"5\",\n" +
             "\"hadoop.security.authentication\" = \"kerberos\",\n" +
diff --git 
a/regression-test/suites/external_table_p0/tvf/test_s3_tvf_number_range.groovy 
b/regression-test/suites/external_table_p0/tvf/test_s3_tvf_number_range.groovy
index 3e84bce35ba..216c869f131 100644
--- 
a/regression-test/suites/external_table_p0/tvf/test_s3_tvf_number_range.groovy
+++ 
b/regression-test/suites/external_table_p0/tvf/test_s3_tvf_number_range.groovy
@@ -15,6 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
+import java.util.concurrent.TimeUnit
+
 suite("test_s3_tvf_number_range", "p0,external") {
 
     String ak = getS3AK()
@@ -351,29 +353,25 @@ suite("test_s3_tvf_number_range", "p0,external") {
             
             // Helper closure to check load result
             def check_hdfs_load_result = {checklabel ->
-                def max_try_milli_secs = 10000
-                def success = false
-                while(max_try_milli_secs) {
-                    def result = sql """ SHOW LOAD WHERE LABEL = 
'${checklabel}' """
+                // Broker Load is asynchronous: cancellation or an unfinished 
job must fail here,
+                // before the caller compares rows in the freshly truncated 
table.
+                long deadline = System.nanoTime() + 
TimeUnit.SECONDS.toNanos(120)
+                def result = []
+                while (System.nanoTime() < deadline) {
+                    result = sql """ SHOW LOAD WHERE LABEL = '${checklabel}' 
"""
                     if (result.size() > 0) {
                         def state = result[0][2]  // State column
                         if (state == "FINISHED") {
                             sql "sync"
-                            success = true
-                            break
-                        } else if (state == "CANCELLED") {
-                            logger.error("HDFS load job ${checklabel} was 
cancelled: ${result[0]}")
-                            break
+                            return
                         }
+                        assertTrue(state != "CANCELLED",
+                                "HDFS load job ${checklabel} was cancelled. 
Status: ${result}")
                     }
-                     sleep(1000) // wait 1 second every time
-                    max_try_milli_secs-=1000
-                }
-                
-                if (!success) {
-                    def result = sql """ SHOW LOAD WHERE LABEL = 
'${checklabel}' """
-                    logger.error("HDFS load job ${checklabel} failed or 
timeout. Status: ${result}")
+                    sleep(1000)
                 }
+                assertTrue(false,
+                        "HDFS load job ${checklabel} did not finish within 120 
seconds. Last status: ${result}")
             }
             
             // Test 12: HDFS Broker Load Single range {1..3} - should load 
{1,2,3}
@@ -407,4 +405,4 @@ suite("test_s3_tvf_number_range", "p0,external") {
         }
     }
     sql """ DROP TABLE IF EXISTS ${test_table} """
-}
\ No newline at end of file
+}
diff --git 
a/regression-test/suites/external_table_p2/paimon/test_paimon_hms_catalog.groovy
 
b/regression-test/suites/external_table_p2/paimon/test_paimon_hms_catalog.groovy
index 01b98dc02b2..c1810ca24be 100644
--- 
a/regression-test/suites/external_table_p2/paimon/test_paimon_hms_catalog.groovy
+++ 
b/regression-test/suites/external_table_p2/paimon/test_paimon_hms_catalog.groovy
@@ -119,11 +119,12 @@ suite("test_paimon_hms_catalog", 
"p2,external,paimon,new_catalog_property") {
       'fs.defaultFS' = 'hdfs://${extHiveHmsHost}:${extHiveHdfsHost}'
     """
 
-    // kerberos
+    // Both Kerberos property forms must match the DataNode SASL protection to 
allow writes.
     String hdfs_kerberos_properties = """
                 "fs.defaultFS" = "hdfs://${extHiveHmsHost}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "hadoop.security.authentication" = "kerberos",           
                 
"hadoop.kerberos.principal"="hive/[email protected]",
@@ -134,6 +135,7 @@ suite("test_paimon_hms_catalog", 
"p2,external,paimon,new_catalog_property") {
                 "fs.defaultFS" = "hdfs://${extHiveHmsHost}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "hdfs.authentication.type" = "kerberos",
                 
"hdfs.authentication.kerberos.principal"="hive/[email protected]",
diff --git 
a/regression-test/suites/external_table_p2/refactor_catalog_param/hive_on_hms_and_dlf.groovy
 
b/regression-test/suites/external_table_p2/refactor_catalog_param/hive_on_hms_and_dlf.groovy
index 62771e46ebc..4055a5aaa0c 100644
--- 
a/regression-test/suites/external_table_p2/refactor_catalog_param/hive_on_hms_and_dlf.groovy
+++ 
b/regression-test/suites/external_table_p2/refactor_catalog_param/hive_on_hms_and_dlf.groovy
@@ -421,11 +421,12 @@ suite("hive_on_hms_and_dlf", 
"p2,external,new_catalog_property") {
     String hdfs_properties = """
                 "hadoop.username" = "doris"
     """
-    // kerberos
+    // Both Kerberos property forms must match the DataNode SASL protection to 
allow writes.
     String hdfs_kerberos_properties = """
                 "fs.defaultFS" = "hdfs://${externalEnvIp}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "hadoop.security.authentication" = "kerberos",
              
@@ -436,6 +437,7 @@ suite("hive_on_hms_and_dlf", 
"p2,external,new_catalog_property") {
                 "fs.defaultFS" = "hdfs://${externalEnvIp}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "hdfs.authentication.type" = "kerberos",
                 
"hdfs.authentication.kerberos.principal"="hive/[email protected]",
diff --git 
a/regression-test/suites/external_table_p2/refactor_catalog_param/iceberg_on_hms_and_filesystem_and_dlf.groovy
 
b/regression-test/suites/external_table_p2/refactor_catalog_param/iceberg_on_hms_and_filesystem_and_dlf.groovy
index fa3cff25572..98ab7ad6039 100644
--- 
a/regression-test/suites/external_table_p2/refactor_catalog_param/iceberg_on_hms_and_filesystem_and_dlf.groovy
+++ 
b/regression-test/suites/external_table_p2/refactor_catalog_param/iceberg_on_hms_and_filesystem_and_dlf.groovy
@@ -474,11 +474,12 @@ suite("iceberg_on_hms_and_filesystem_and_dlf", 
"p2,external,new_catalog_property
     String hdfs_properties = """
                 "hadoop.username" = "doris"
     """
-    // kerberos
+    // Both Kerberos property forms must match the DataNode SASL protection to 
allow writes.
     String hdfs_kerberos_properties = """
                 "fs.defaultFS" = "hdfs://${externalEnvIp}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "hadoop.security.authentication" = "kerberos", 
                 "io-impl" = 
"org.apache.doris.datasource.iceberg.fileio.DelegateFileIO",          
@@ -490,6 +491,7 @@ suite("iceberg_on_hms_and_filesystem_and_dlf", 
"p2,external,new_catalog_property
                 "fs.defaultFS" = "hdfs://${externalEnvIp}:8520",
                 "dfs.namenode.kerberos.principal" = 
"hdfs/[email protected]",
                 "dfs.client.use.datanode.hostname" = "true",
+                "dfs.data.transfer.protection" = "authentication",
                 "hadoop.security.token.service.use_ip" = "false",
                 "io-impl" = 
"org.apache.doris.datasource.iceberg.fileio.DelegateFileIO",          
                 "hdfs.authentication.type" = "kerberos",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to