apache/seatunnel · warning

Primary key( ) is nullable for catalog table

Error message

Primary key({}) is nullable for catalog table {}

What it means

CatalogTableUtils.mergeCatalogTableConfig overrides CDC table columns: when a configured primary key column is nullable in the discovered catalog table schema, it is replaced with a non-nullable PhysicalColumn and this warning is logged. Sink primary keys must be non-nullable; a nullable primary key would break upsert/key-based writes.

Solutions

  1. Choose a truly non-nullable column (or column set) as the primary key in the config.
  2. Alter the source table so the primary key column is NOT NULL.
  3. If the source genuinely has no usable primary key, configure the connector's debezium primary key handling or use a different key strategy.
  4. Verify the effective schema after merge; the util already coerces nullability, so this warning mainly flags a risky key choice.

Example fix

// before
catalog-tables = [{ table = "mydb.events", primary-keys = ["optional_col"] }] // nullable
// after: pick a non-nullable key
catalog-tables = [{ table = "mydb.events", primary-keys = ["id"] }]
Defensive patterns

Strategy: validation

Validate before calling

// ensure configured primary keys are non-nullable in source schema
for (String pk : config.getPrimaryKeys()) {
  Column c = schema.getColumn(pk);
  if (c != null && c.isNullable()) throw new IllegalArgumentException("nullable PK: " + pk);
}

Type guard

if (column.isNullable() && config.getPrimaryKeys().contains(column.getName())) coerceToNonNull(column);

Try / catch

// warning-only coercion; choose valid keys instead

Prevention

When it happens

Trigger: A catalog table config declares primary keys that are nullable columns in the source schema (e.g. a unique-but-nullable index used as PK, or discovered schema marking PK columns nullable).

Common situations: Sources like MySQL where the discovered schema misreports nullability; users choosing secondary/nullable unique keys as primary-keys; views or tables without true primary keys.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/utils/CatalogTableUtils.java:92

        for (String pk : config.getPrimaryKeys()) {
            if (!columnNames.contains(pk)) {
                throw new IllegalArgumentException(
                        String.format(
                                "Primary key(%s) is not in table(%s) columns(%s)",
                                pk, table.getTablePath(), columnNames));
            }
        }
        PrimaryKey primaryKeys =
                PrimaryKey.of(
                        "pk" + (config.getPrimaryKeys().hashCode() & Integer.MAX_VALUE),
                        config.getPrimaryKeys());
        List<Column> columns =
                table.getTableSchema().getColumns().stream()
                        .map(
                                column -> {
                                    if (config.getPrimaryKeys().contains(column.getName())
                                            && column.isNullable()) {
                                        log.warn(
                                                "Primary key({}) is nullable for catalog table {}",
                                                column.getName(),
                                                table.getTablePath());
                                        return PhysicalColumn.of(
                                                column.getName(),
                                                column.getDataType(),
                                                column.getColumnLength(),
                                                false,
                                                column.getDefaultValue(),
                                                column.getComment());
                                    }
                                    return column;
                                })
                        .collect(Collectors.toList());

        return CatalogTable.of(
                table.getTableId(),
                TableSchema.builder()

View on GitHub (pinned to cf67b549a7)