apache/seatunnel · error · HudiConnectorException

TABLE_CONFIG_NOT_FOUND

TABLE_CONFIG_NOT_FOUND

Error message

The corresponding table ${tableName} is not found in the table list of hudi sink config.

What it means

createHoodieJavaWriteClient looks up the table being written in the hudi sink's configured table list. When no HudiTableConfig whose tableName matches is present, it throws TABLE_CONFIG_NOT_FOUND because the sink cannot know the target hoodie table's settings (record keys, precombine field, etc.).

Source

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

            UserGroupInformation.setConfiguration(conf);
            UserGroupInformation.loginUserFromKeytab(principal, principalFile);
        } catch (IOException e) {
            throw new HudiConnectorException(
                    CommonErrorCodeDeprecated.KERBEROS_AUTHORIZED_FAILED,
                    "Kerberos Authorized Fail!",
                    e);
        }
    }

    public static HoodieJavaWriteClient<HoodieAvroPayload> createHoodieJavaWriteClient(
            HudiSinkConfig hudiSinkConfig, SeaTunnelRowType seaTunnelRowType, String tableName) {
        List<HudiTableConfig> tableList = hudiSinkConfig.getTableList();
        Optional<HudiTableConfig> hudiTableConfig =
                tableList.stream()
                        .filter(table -> table.getTableName().equals(tableName))
                        .findFirst();
        if (!hudiTableConfig.isPresent()) {
            throw new HudiConnectorException(
                    TABLE_CONFIG_NOT_FOUND,
                    "The corresponding table "
                            + tableName
                            + " is not found in the table list of hudi sink config.");
        }
        Configuration hadoopConf = getConfiguration(hudiSinkConfig.getConfFilesPath());

        HudiTableConfig hudiTable = hudiTableConfig.get();
        HoodieWriteConfig.Builder writeConfigBuilder = HoodieWriteConfig.newBuilder();
        // build index config
        if (Objects.nonNull(hudiTable.getIndexClassName())) {
            writeConfigBuilder.withIndexConfig(
                    HoodieIndexConfig.newBuilder()
                            .withIndexClass(hudiTable.getIndexClassName())
                            .build());
        } else {
            writeConfigBuilder.withIndexConfig(
                    HoodieIndexConfig.newBuilder().withIndexType(hudiTable.getIndexType()).build());

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add the missing table to the hudi sink table_list config, matching tableName exactly.
  2. Check for case/qualified-name mismatches: the config value must equal getTableName() on the incoming table exactly (no db prefix unless configured that way).
  3. Log or dump the resolved tableName at runtime and diff it against the configured list.
  4. If tables are dynamic, validate the set of upstream tables against the config before job submission.

Example fix

// before
sink {
  Hudi {
    table_list = [
      { table_name = "orders" ... }
    ]
  }
}
// after
sink {
  Hudi {
    table_list = [
      { table_name = "orders" ... },
      { table_name = "customers" ... }   // table present in upstream data
    ]
  }
}
Defensive patterns

Strategy: validation

Validate before calling

Set<String> configured = sinkConfig.getTableList().stream()
    .map(HudiTableConfig::getTableName).collect(Collectors.toSet());
if (!configured.contains(tableName)) {
    throw new IllegalArgumentException("table not in hudi sink table_list: " + tableName);
}

Try / catch

try {
    HoodieJavaWriteClient<?> client = HudiUtil.createHoodieJavaWriteClient(config, tableName);
} catch (HudiConnectorException e) {
    LOG.error("table {} missing from hudi sink table_list", tableName, e);
    throw e;
}

Prevention

When it happens

Trigger: Writing to a Hudi table via HudiUtil.createHoodieJavaWriteClient where tableName from the incoming data/catalog does not equal any table.tableName entry in the sink config's table_list.

Common situations: Typo or case mismatch between the configured table name and the actual table; upstream data contains a table not added to the sink's table list; catalog/database-qualified names (db.table) configured differently from the plain tableName used at lookup.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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