apache/iceberg · error · DataException
Unable to create table from empty object
Error message
Unable to create table from empty object
What it means
IcebergWriterFactory.autoCreateTable infers the Iceberg schema for the new table from a sample SinkRecord. When the record has no value schema, it infers the type from the raw value; if that inference returns null (value is null or an empty/unsupported object), table creation cannot proceed and a DataException is thrown.
Solutions
- Pre-create the target Iceberg table with an explicit schema instead of relying on auto-creation.
- Ensure the topic carries records with real, non-null, non-empty values and a value schema (use Avro/Protobuf with schema registry, or ensure JSON converter emits schemas).
- Check the producer/converter config so tombstones or empty messages are not the records used for schema inference.
- Verify table_create/auto-create properties point at the correct topic-to-table mapping with a valid sample record available.
Example fix
// before
// auto-create from a topic whose sampled record has null schema/value
// "iceberg.sink.auto-create-table": "true"
// after
// pre-create the table explicitly
spark.sql("CREATE TABLE catalog.db.topic_table (id long, ts timestamp) USING iceberg"); Defensive patterns
Strategy: validation
Validate before calling
// Java — check the sample before relying on auto-creation
boolean canAutoCreate = sample.value() != null &&
(sample.valueSchema() != null || sample.value() instanceof Map && !((Map<?, ?>) sample.value()).isEmpty()); Try / catch
try {
Table table = factory.autoCreateTable(tableName, sample);
} catch (DataException e) {
if (String.valueOf(e.getMessage()).contains("Unable to create table from empty object")) {
LOG.error("Sample record has no schema/empty value — pre-create table {} explicitly", tableName, e);
}
throw e;
} Prevention
- Pre-create Iceberg tables with explicit schemas instead of auto-creating from topic samples
- Use schema-carrying formats (Avro/Protobuf + schema registry) on the source topic
- Ensure tombstones/empty messages are not the records sampled at connector start
- Verify the value converter is configured to emit schemas (e.g. schemas.enable=true for JSON)
When it happens
Trigger: auto-create-table is enabled and the sampled record's valueSchema() is null while its value() yields no inferable type — e.g. null payloads (tombstones), empty maps/structs, or unsupported value shapes reaching the sampler.
Common situations: Topic's first/most recent record is a tombstone (null value) at connector start; producer sending schema-less formats (raw JSON/bytes) with empty objects; misconfigured value converter producing null values.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- An error occurred closing catalog instance, ignoring...
- An error occurred converting record, topic
- Cannot convert date
- Cannot convert java.util.Date to variant without a…
- Cannot convert map to variant: keys must be non-null…
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4fd11076de5245a7.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/IcebergWriterFactory.java:89
UUID tableUuid = table.uuid();
if (tableUuid == null) {
LOG.warn(
"Table {} does not have a UUID, this may cause issues with commit coordination on table replace",
identifier);
}
TableReference tableReference = TableReference.of(catalog.name(), identifier, tableUuid);
return new IcebergWriter(table, tableReference, config);
}
@VisibleForTesting
Table autoCreateTable(String tableName, SinkRecord sample) {
StructType structType;
if (sample.valueSchema() == null) {
Type type = SchemaUtils.inferIcebergType(sample.value(), config);
if (type == null) {
throw new DataException("Unable to create table from empty object");
}
structType = type.asStructType();
} else {
structType = SchemaUtils.toIcebergType(sample.valueSchema(), config).asStructType();
}
org.apache.iceberg.Schema schema = new org.apache.iceberg.Schema(structType.fields());
TableIdentifier identifier = TableIdentifier.parse(tableName);
createNamespaceIfNotExist(catalog, identifier.namespace());
List<String> partitionBy = config.tableConfig(tableName).partitionBy();
PartitionSpec spec;
try {
spec = SchemaUtils.createPartitionSpec(schema, partitionBy);
} catch (Exception e) {
LOG.error(
"Unable to create partition spec {}, table {} will be unpartitioned",View on GitHub (pinned to 86d9c8fc54)