apache/iceberg · error
Invalid default value for %s: %s (must be null)
Error message
Invalid default value for %s: %s (must be null)
What it means
Thrown by Types.NestedField's castDefault when a non-null initialDefault or writeDefault is supplied for a nested-typed field (struct, list, map, variant). Defaults for nested types must be null; only primitive-typed fields accept non-null literal defaults.
Source
Thrown at api/src/main/java/org/apache/iceberg/types/Types.java:897
Literal<?> writeDefault) {
Preconditions.checkNotNull(name, "Name cannot be null");
Preconditions.checkNotNull(type, "Type cannot be null");
Preconditions.checkArgument(
isOptional || !type.equals(UnknownType.get()),
"Cannot create required field with unknown type: %s",
name);
this.isOptional = isOptional;
this.id = id;
this.name = name;
this.type = type;
this.doc = doc;
this.initialDefault = castDefault(initialDefault, type);
this.writeDefault = castDefault(writeDefault, type);
}
private static Literal<?> castDefault(Literal<?> defaultValue, Type type) {
if (type.isNestedType() && defaultValue != null) {
throw new IllegalArgumentException(
String.format("Invalid default value for %s: %s (must be null)", type, defaultValue));
} else if (defaultValue != null) {
Literal<?> typedDefault = defaultValue.to(type);
Preconditions.checkArgument(
typedDefault != null, "Cannot cast default value to %s: %s", type, defaultValue);
return typedDefault;
}
return null;
}
public boolean isOptional() {
return isOptional;
}
public NestedField asOptional() {
if (isOptional) {
return this;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Pass null (or omit withInitialDefault/withWriteDefault) for fields whose type is nested
- Only set literal defaults when the field type is a primitive type
- Add a check in schema-building code: if (fieldType.isNestedType()) skip setting the default
Example fix
// before
Types.NestedField.optional(1, "items", Types.ListType.ofOptional(2, Types.StringType.get()))
.withInitialDefault(literal("x"))
// after
Types.NestedField.optional(1, "items", Types.ListType.ofOptional(2, Types.StringType.get())) Defensive patterns
Strategy: validation
Validate before calling
if (fieldType.isNestedType() && initialDefault != null) {
throw new IllegalArgumentException("Defaults must be null for nested type: " + fieldType);
} Try / catch
try {
builder.withInitialDefault(literal);
} catch (IllegalArgumentException e) {
// nested type: retry without a default
} Prevention
- Only set field defaults when Types.NestedField.type().isPrimitiveType() is true
- Guard schema builders with a nested-type check before applying defaults
- Keep default-value application in one utility so the guard is enforced everywhere
When it happens
Trigger: Building a NestedField with Types.NestedField.required/optional(...).withInitialDefault(someLiteral) (or withWriteDefault) where the field's type is a nested type and the literal is non-null.
Common situations: Programmatic schema builders that blanket-apply defaults to all fields; schema evolution code copying defaults from a primitive field template to nested fields; DDL translation where source engines allow nested defaults but Iceberg does not.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Cannot convert nested accessor to position
- Field + name + not found in source schema
- Cannot parse type string to primitive: + typeString
- Unsupported type in partition data:
- Cannot parse default as a %s value: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/cefb86025c2677e0.
Report an issue: GitHub.