apache/iceberg · warning

Invalid value for (negative): , falling back to

Error message

Invalid value for {} (negative): {}, falling back to {}

What it means

MetricsConfig validates the table property write.metrics.max-inferred-column-defaults. If the configured value is a negative integer, the config is rejected with this warning and the default value is used instead of failing the write.

Solutions

  1. Set write.metrics.max-inferred-column-defaults to a non-negative integer (0 disables, larger values increase inference).
  2. Remove the property to fall back to the built-in default.
  3. Audit table and catalog-level properties for negative values before tuning.

Example fix

// before
ALTER TABLE t SET TBLPROPERTIES ('write.metrics.max-inferred-column-defaults'='-1');
// after
ALTER TABLE t SET TBLPROPERTIES ('write.metrics.max-inferred-column-defaults'='100');
Defensive patterns

Strategy: validation

Validate before calling

int v = Integer.parseInt(props.getProperty("write.metrics.max-inferred-column-defaults"));
if (v < 0) throw new IllegalArgumentException("must be >= 0: " + v);

Prevention

When it happens

Trigger: Setting table property 'write.metrics.max-inferred-column-defaults' to a negative number (e.g. -1) via ALTER TABLE TBLPROPERTIES or catalog configuration, then performing a write that builds MetricsConfig.

Common situations: Copy-pasted config from another property where negative means unlimited, typos in tuning attempts, or migrating configs where -1 was accepted elsewhere.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/30fd2bdb8212f6fd. Report an issue: GitHub.

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/MetricsConfig.java:342

   * @param defaultMode default mode
   * @return mode to use
   */
  private static MetricsMode sortedColumnDefaultMode(MetricsMode defaultMode) {
    if (defaultMode == MetricsModes.None.get() || defaultMode == MetricsModes.Counts.get()) {
      return MetricsModes.Truncate.withLength(16);
    } else {
      return defaultMode;
    }
  }

  private static int maxInferredColumnDefaults(Map<String, String> properties) {
    int maxInferredDefaultColumns =
        PropertyUtil.propertyAsInt(
            properties,
            METRICS_MAX_INFERRED_COLUMN_DEFAULTS,
            METRICS_MAX_INFERRED_COLUMN_DEFAULTS_DEFAULT);
    if (maxInferredDefaultColumns < 0) {
      LOG.warn(
          "Invalid value for {} (negative): {}, falling back to {}",
          METRICS_MAX_INFERRED_COLUMN_DEFAULTS,
          maxInferredDefaultColumns,
          METRICS_MAX_INFERRED_COLUMN_DEFAULTS_DEFAULT);
      return METRICS_MAX_INFERRED_COLUMN_DEFAULTS_DEFAULT;
    } else {
      return maxInferredDefaultColumns;
    }
  }

  private static MetricsMode parseMode(String modeString, MetricsMode fallback, String context) {
    try {
      return MetricsModes.fromString(modeString);
    } catch (IllegalArgumentException err) {
      // User override was invalid, log the error and use the default
      LOG.warn("Ignoring invalid metrics mode ({}): {}", context, modeString, err);
      return fallback;
    }

View on GitHub (pinned to 86d9c8fc54)