prestodb/presto · error · PrestoException

ICEBERG_INVALID_FORMAT_VERSION

ICEBERG_INVALID_FORMAT_VERSION

Error message

Unable to parse user provided format version

What it means

parseFormatVersion converts a user-supplied format version string to an int with parseInt. If the string is not a valid integer (or is out of bounds), it throws ICEBERG_INVALID_FORMAT_VERSION. This distinguishes malformed input from a valid-but-unsupported version (which raises NOT_SUPPORTED instead).

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/IcebergUtil.java:1460

        propertiesBuilder.put(SPLIT_SIZE, String.valueOf(IcebergTableProperties.getTargetSplitSize(tableMetadata.getProperties())));

        isHiveLocksEnabled(tableMetadata.getProperties()).ifPresent(value -> propertiesBuilder.put(HIVE_LOCK_ENABLED, value));

        return propertiesBuilder.build();
    }

    public static int parseFormatVersion(String formatVersion)
    {
        try {
            int version = parseInt(formatVersion);
            if (version > MAX_SUPPORTED_FORMAT_VERSION) {
                throw new PrestoException(NOT_SUPPORTED, format("Iceberg table format version %d is not supported", version));
            }
            return version;
        }
        catch (NumberFormatException | IndexOutOfBoundsException e) {
            throw new PrestoException(ICEBERG_INVALID_FORMAT_VERSION, "Unable to parse user provided format version");
        }
    }

    public static RowLevelOperationMode getDeleteMode(Table table)
    {
        return RowLevelOperationMode.fromName(table.properties()
                .getOrDefault(DELETE_MODE, DELETE_MODE_DEFAULT)
                .toUpperCase(Locale.ENGLISH));
    }

    public static RowLevelOperationMode getUpdateMode(Table table)
    {
        return RowLevelOperationMode.fromName(table.properties()
                .getOrDefault(UPDATE_MODE, UPDATE_MODE_DEFAULT)
                .toUpperCase(Locale.ENGLISH));
    }

    public static int getMetadataPreviousVersionsMax(Table table)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Set the format version to a plain integer string (e.g. '1' or '2'), not 'v1', '1.0', or a placeholder
  2. Check the session property / catalog config that supplies format_version and remove nulls or empty values
  3. Ensure any tooling generating the property emits an unquoted integer without suffixes or whitespace

Example fix

// before
SET SESSION iceberg.format_version = 'v2';
// after
SET SESSION iceberg.format_version = '2';
Defensive patterns

Strategy: validation

Validate before calling

if (formatVersion == null || !formatVersion.trim().matches("^\\d+$")) {
    throw new IllegalArgumentException(
        "format version must be a plain integer string, got: " + formatVersion);
}

Try / catch

try {
    int v = IcebergUtil.parseFormatVersion(raw);
} catch (PrestoException e) {
    if (e.getErrorCode() == ICEBERG_INVALID_FORMAT_VERSION.toErrorCode()) {
        // log raw value and default to a supported version
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling IcebergUtil.parseFormatVersion with a null, empty, non-numeric, or otherwise unparseable string (e.g. 'abc', '', 'v2', '1.5').

Common situations: Typo in a session/catalog property value; a config template left with a placeholder like '${FORMAT_VERSION}'; passing a version qualifier like '2.0' where only plain integers are accepted.

Understand the failure class

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/0e70a20852403339. Report an issue: GitHub.