apache/seatunnel · error · HudiConnectorException

TABLE_SCHEMA_GET_FAILED

TABLE_SCHEMA_GET_FAILED

Error message

Create ParquetMetadata Fail!

What it means

HudiUtil.getSeaTunnelRowTypeInfo reads a Parquet footer from the table directory to infer the SeaTunnel row type; if ParquetFileReader.readFooter throws IOException it wraps it in HudiConnectorException (TABLE_SCHEMA_GET_FAILED) with 'Create ParquetMetadata Fail!'.

Source

Thrown at seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/util/HudiUtil.java:104

            }
            if (fileStatus.isFile()) {
                if (fileStatus.getPath().toString().endsWith("parquet")) {
                    return fileStatus.getPath().toString();
                }
            }
        }
        return null;
    }

    public static SeaTunnelRowType getSeaTunnelRowTypeInfo(String confPaths, String path)
            throws HudiConnectorException {
        Configuration configuration = getConfiguration(confPaths);
        Path dstDir = new Path(path);
        ParquetMetadata footer;
        try {
            footer = ParquetFileReader.readFooter(configuration, dstDir, NO_FILTER);
        } catch (IOException e) {
            throw new HudiConnectorException(
                    CommonErrorCodeDeprecated.TABLE_SCHEMA_GET_FAILED,
                    "Create ParquetMetadata Fail!",
                    e);
        }
        MessageType schema = footer.getFileMetaData().getSchema();
        String[] fields = new String[schema.getFields().size()];
        SeaTunnelDataType[] types = new SeaTunnelDataType[schema.getFields().size()];

        for (int i = 0; i < schema.getFields().size(); i++) {
            fields[i] = schema.getFields().get(i).getName();
            types[i] = BasicType.STRING_TYPE;
        }
        return new SeaTunnelRowType(fields, types);
    }

    public static JobConf toJobConf(Configuration conf) {
        if (conf instanceof JobConf) {
            return (JobConf) conf;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Verify the table path contains valid Parquet data files before starting
  2. Fix the HDFS conf paths configuration so the reader can access the cluster
  3. Check read permissions on the table directory for the job user
  4. Upgrade/align Parquet/Hudi versions if files are unreadable

Example fix

// before: conf paths missing -> readFooter fails with IOException
// after
"hdfs_conf_paths" = ["/etc/hadoop/core-site.xml", "/etc/hadoop/hdfs-site.xml"]
Defensive patterns

Strategy: try-catch

Validate before calling

// before running, ensure table dir has parquet files and hdfs confs exist
Path p = new Path(tablePath);
FileSystem fs = p.getFileSystem(conf);
if (!fs.exists(p) || !fs.listStatus(p, f -> f.getPath().getName().endsWith(".parquet")).hasNext()) {
    throw new IllegalStateException("No Parquet files under " + tablePath + "; schema inference will fail");
}

Try / catch

try {
    SeaTunnelRowType type = HudiUtil.getSeaTunnelRowTypeInfo(confPaths, tablePath);
} catch (HudiConnectorException e) {
    if ("Create ParquetMetadata Fail!".equals(e.getErrorMessage())) {
        LOG.error("Footer read failed; check path/data files/hdfs conf; cause: {}", e.getCause(), e.getCause());
    } else { throw e; }
}

Prevention

When it happens

Trigger: readFooter fails on the given path: directory has no/broken Parquet files, path doesn't exist, wrong conf paths (missing HDFS config), or permission/IO errors.

Common situations: Empty table directory with no data files yet; misconfigured hdfs conf paths; reading a table written by an incompatible Parquet writer; network/permission issues on HDFS.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/4e4748fbbee10474. Report an issue: GitHub.