This is an automated email from the ASF dual-hosted git repository.
yihua pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git
The following commit(s) were added to refs/heads/master by this push:
new 1846230d84de fix: throw correct exception when reading
hoodie.properties file without access (#18176)
1846230d84de is described below
commit 1846230d84deb124992e995e203b118b13105286
Author: Surya Prasanna <[email protected]>
AuthorDate: Thu Feb 12 13:22:42 2026 -0800
fix: throw correct exception when reading hoodie.properties file without
access (#18176)
---
.../org/apache/hudi/common/util/ConfigUtils.java | 7 +++-
.../hudi/common/util/HoodieExceptionUtil.java | 41 ++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git
a/hudi-common/src/main/java/org/apache/hudi/common/util/ConfigUtils.java
b/hudi-common/src/main/java/org/apache/hudi/common/util/ConfigUtils.java
index a2003d3caa92..5f0ce3bbb9a0 100644
--- a/hudi-common/src/main/java/org/apache/hudi/common/util/ConfigUtils.java
+++ b/hudi-common/src/main/java/org/apache/hudi/common/util/ConfigUtils.java
@@ -681,7 +681,12 @@ public class ConfigUtils {
}
return props;
} catch (IOException e) {
- log.warn("Could not read properties from {}: {}", path, e);
+ if (HoodieExceptionUtil.isPermissionDeniedException(e)) {
+ log.error("Permission denied for " + path.toString() + " file.",
e);
+ throw new HoodieIOException("Permission denied for " + path + "
file path. User does not have read access on the dataset.", e);
+ } else {
+ log.warn("Could not read properties from {}: {}", path, e);
+ }
} catch (IllegalArgumentException e) {
log.warn("Invalid properties file {}: {}", path, props);
}
diff --git
a/hudi-io/src/main/java/org/apache/hudi/common/util/HoodieExceptionUtil.java
b/hudi-io/src/main/java/org/apache/hudi/common/util/HoodieExceptionUtil.java
new file mode 100644
index 000000000000..1f55fb59f5b1
--- /dev/null
+++ b/hudi-io/src/main/java/org/apache/hudi/common/util/HoodieExceptionUtil.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hudi.common.util;
+
+import java.io.IOException;
+
+/**
+ * Utility class for exception handling and analysis.
+ */
+public class HoodieExceptionUtil {
+
+ /**
+ * Checks if the given IOException is a permission denied error.
+ * This works across different storage implementations (Hadoop, S3, GCS,
etc.)
+ * by checking both the exception class name and message.
+ *
+ * @param e the IOException to check
+ * @return true if the exception indicates permission denied, false otherwise
+ */
+ public static boolean isPermissionDeniedException(IOException e) {
+ return e.getClass().getSimpleName().contains("AccessControl")
+ || (e.getMessage() != null && (e.getMessage().contains("Permission
denied")
+ || e.getMessage().contains("Access denied")));
+ }
+}