apache/iceberg · error · IllegalArgumentException
Invalid unit: %s
Error message
Invalid unit: %s
What it means
MetricsContext.Unit.fromDisplayName converts a user-facing unit string to the Unit enum, uppercasing it first; null throws 'Invalid unit: null' and any string that is not a valid Unit name (bytes, bytes_i32, bytes_i64, count, none, timestamps, time) throws 'Invalid unit: <value>'. It preserves the cause from Unit.valueOf.
Source
Thrown at api/src/main/java/org/apache/iceberg/metrics/MetricsContext.java:53
BYTES("bytes"),
COUNT("count");
private final String displayName;
Unit(String displayName) {
this.displayName = displayName;
}
public String displayName() {
return displayName;
}
public static Unit fromDisplayName(String displayName) {
Preconditions.checkArgument(null != displayName, "Invalid unit: null");
try {
return Unit.valueOf(displayName.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(String.format("Invalid unit: %s", displayName), e);
}
}
}
default void initialize(Map<String, String> properties) {}
/**
* @deprecated will be removed in 2.0.0, use {@link org.apache.iceberg.metrics.Counter} instead.
*/
@Deprecated
interface Counter<T extends Number> {
/** Increment the counter by a single whole number value (i.e. 1). */
void increment();
/**
* Increment the counter by the provided amount.
*
* @param amount to be incrementedView on GitHub (pinned to 86d9c8fc54)
Solutions
- Use one of the exact Unit enum names (case-insensitive): bytes, bytes_i32, bytes_i64, count, none, timestamps, time
- Check the property value for typos or whitespace before calling fromDisplayName
- Guard against null/empty input before conversion
- Catch IllegalArgumentException and fall back to a default Unit
Example fix
// before
Unit u = Unit.fromDisplayName(props.get("unit"));
// after
String raw = props.get("unit");
Unit u = (raw != null && !raw.isEmpty())
? Unit.fromDisplayName(raw)
: Unit.COUNT; Defensive patterns
Strategy: validation
Validate before calling
if (displayName == null || displayName.isEmpty()) { default; } Try / catch
try { Unit.fromDisplayName(s); } catch (IllegalArgumentException e) { use default; } Prevention
- Use exact enum names in configs
- Trim inputs
- Validate at config load
When it happens
Trigger: Parsing a metrics unit from a table/user property (e.g. 'counter-unit') that is misspelled, empty-but-non-null, or in a different language/lowercase abbreviation like 'b' or 'counts'.
Common situations: Config mistakes in properties files (e.g. 'bytese', 'Counts'); users passing human-friendly units like 'bytes' vs enum names like 'BYTES' — note fromDisplayName uppercases, so only exact enum names case-insensitively work; locale issues.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- NOOP counter has no value
- integer overflow
- Counter for type %s is not supported
- Count is not supported.
- Counter is not supported.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ee208a6d454e70fc.
Report an issue: GitHub.