apache/iceberg · error · IllegalArgumentException
Invalid metrics mode:
Error message
Invalid metrics mode:
What it means
MetricsModes.fromString parses a table property value (write.metadata.metrics.default/column, e.g. 'none', 'all', 'counts', 'truncate(L)') into a MetricsModes instance and throws IllegalArgumentException when the string matches none of the known patterns. The value is either misspelled or uses an unsupported truncate syntax.
Solutions
- Use one of the valid modes exactly: 'none', 'all', 'counts', or 'truncate(N)' where N is a positive integer.
- Check for typos/extra whitespace in the property value; parsing is case-insensitive but spelling must be exact.
- If truncating, ensure the format is truncate(16) — no spaces, integer length, spelled out fully.
Example fix
// before
table.updateProperties().set("write.metadata.metrics.default", "trunc(16)");
// after
table.updateProperties().set("write.metadata.metrics.default", "truncate(16)"); Defensive patterns
Strategy: validation
Validate before calling
String mode = props.get("write.metadata.metrics.default");
if (mode != null && !mode.matches("(?i)none|all|counts|truncate\\(\\d+\\)")) {
throw new IllegalArgumentException("Invalid metrics mode: " + mode);
} Try / catch
try {
MetricsModes.fromString(mode);
} catch (IllegalArgumentException e) {
MetricsModes metricsMode = MetricsModes.None.get(); // safe default
} Prevention
- Only use the documented values: none, all, counts, truncate(N).
- Validate table properties on write (e.g. in SQL or CI) rather than at scan time.
- Remember parsing is case-insensitive but whitespace-sensitive — trim inputs.
When it happens
Trigger: Setting table property 'write.metadata.metrics.default' or a per-column metric property to a value like 'trunc(16)', 'Truncate', 'truncated(10)', or any empty/garbage string that is not none/all/counts/truncate(<n>).
Common situations: Typos in table properties via SQL ('ALTER TABLE ... SET TBLPROPERTIES'), Spark/Flink config, or catalog configuration files; truncating with invalid syntax like 'truncate()' or non-integer length.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Unknown planning mode:
- AboveMax has no value
- apply(value) is deprecated, use bind(Type).apply(value)
- apply(value) is deprecated, use bind(Type).apply(value)
- Backup table name cannot be specified
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/3406a2a4c1fe99bc.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/MetricsModes.java:54
private MetricsModes() {}
public static MetricsMode fromString(String mode) {
if ("none".equalsIgnoreCase(mode)) {
return None.get();
} else if ("counts".equalsIgnoreCase(mode)) {
return Counts.get();
} else if ("full".equalsIgnoreCase(mode)) {
return Full.get();
}
Matcher truncateMatcher = TRUNCATE.matcher(mode.toLowerCase(Locale.ROOT));
if (truncateMatcher.matches()) {
int length = Integer.parseInt(truncateMatcher.group(1));
return Truncate.withLength(length);
}
throw new IllegalArgumentException("Invalid metrics mode: " + mode);
}
/**
* A metrics calculation mode.
*
* <p>Implementations must be immutable.
*/
public interface MetricsMode extends Serializable {
default boolean hasBounds() {
throw new UnsupportedOperationException(
"Unexpected implementation of MetricsMode without hasBounds");
}
}
/**
* Under this mode, value_counts, null_value_counts, nan_value_counts, lower_bounds, upper_bounds
* are not persisted.
*/View on GitHub (pinned to 86d9c8fc54)