apache/iceberg · error · org.apache.flink.table.api.ValidationException

Invalid primary key '%s'. Column '%s' is nullable.

Error message

Invalid primary key '%s'. Column '%s' is nullable.

What it means

validatePrimaryKey checks that each primary key column's logical type is non-nullable; a nullable key column makes the row identifier meaningless for upserts. It throws ValidationException naming the key and the nullable column.

Source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/FlinkSchemaUtil.java:373

    for (String columnName : primaryKey.getColumns()) {
      Column column = columnsByNameLookup.get(columnName);
      if (column == null) {
        throw new ValidationException(
            String.format(
                "Invalid primary key '%s'. Column '%s' does not exist.",
                primaryKey.getName(), columnName));
      }

      if (!column.isPhysical()) {
        throw new ValidationException(
            String.format(
                "Invalid primary key '%s'. Column '%s' is not a physical column.",
                primaryKey.getName(), columnName));
      }

      final LogicalType columnType = column.getDataType().getLogicalType();
      if (columnType.isNullable()) {
        throw new ValidationException(
            String.format(
                "Invalid primary key '%s'. Column '%s' is nullable.",
                primaryKey.getName(), columnName));
      }
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Declare the primary key column as NOT NULL in the schema/DDL.
  2. When building fields programmatically, wrap the type with DataTypes.FIELD(..., type.NOT_NULL()).
  3. Pick a different non-nullable column (or a combination of such) as the key.

Example fix

// before
id INT, name STRING, PRIMARY KEY (id) NOT ENFORCED
// after
id INT NOT NULL, name STRING, PRIMARY KEY (id) NOT ENFORCED
Defensive patterns

Strategy: validation

Validate before calling

for (String c : primaryKey.getColumns()) {
  Column col = schema.getColumn(c).orElseThrow();
  if (col.getDataType().getLogicalType().isNullable()) {
    throw new IllegalArgumentException("PK column must be NOT NULL: " + c);
  }
}

Try / catch

try {
  ResolvedSchema rs = FlinkSchemaUtil.toResolvedSchema(schema);
} catch (ValidationException e) {
  // message names the nullable column; add NOT NULL
}

Prevention

When it happens

Trigger: toResolvedSchema with a PRIMARY KEY whose column type is nullable — e.g. a column declared without NOT NULL but included in PRIMARY KEY (id) NOT ENFORCED.

Common situations: Forgetting NOT NULL on key columns in DDL; building a DataTypes.RowField for the key column without NOT NULL; schemas imported from sources that allow nulls.

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/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/8518819554321312. Report an issue: GitHub.