prestodb/presto · error · IllegalArgumentException

invalid mapping format '%s' for column '%s'

Error message

invalid mapping format '%s' for column '%s'

What it means

RawColumnDecoder's constructor parses the column's mapping with pattern (\d+)(?::(\d+))? — either a single byte offset or a 'start:end' byte range. If mapping does not match (e.g. contains letters, commas, or negative numbers), the constructor throws IllegalArgumentException "invalid mapping format '%s' for column '%s'" during table metadata construction.

Source

Thrown at presto-record-decoder/src/main/java/com/facebook/presto/decoder/raw/RawColumnDecoder.java:103

            checkArgument(!columnHandle.isInternal(), "unexpected internal column '%s'", columnHandle.getName());
            checkArgument(columnHandle.getFormatHint() == null, "unexpected format hint '%s' defined for column '%s'", columnHandle.getFormatHint(), columnHandle.getName());

            columnName = columnHandle.getName();
            columnType = columnHandle.getType();

            try {
                fieldType = columnHandle.getDataFormat() == null ?
                        FieldType.BYTE :
                        FieldType.valueOf(columnHandle.getDataFormat().toUpperCase(Locale.ENGLISH));
            }
            catch (IllegalArgumentException e) {
                throw new IllegalArgumentException(format("invalid dataFormat '%s' for column '%s'", columnHandle.getDataFormat(), columnName));
            }

            String mapping = Optional.ofNullable(columnHandle.getMapping()).orElse("0");
            Matcher mappingMatcher = MAPPING_PATTERN.matcher(mapping);
            if (!mappingMatcher.matches()) {
                throw new IllegalArgumentException(format("invalid mapping format '%s' for column '%s'", mapping, columnName));
            }
            start = parseInt(mappingMatcher.group(1));
            if (mappingMatcher.group(2) != null) {
                end = OptionalInt.of(parseInt(mappingMatcher.group(2)));
            }
            else {
                if (!isVarcharType(columnType)) {
                    end = OptionalInt.of(start + fieldType.getSize());
                }
                else {
                    end = OptionalInt.empty();
                }
            }

            checkArgument(start >= 0, "start offset %s for column '%s' must be greater or equal 0", start, columnName);
            end.ifPresent(endValue -> {
                checkArgument(endValue >= 0, "end offset %s for column '%s' must be greater or equal 0", endValue, columnName);
                checkArgument(endValue >= start, "end offset %s for column '%s' must greater or equal start offset", endValue, columnName);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Use 'start' or 'start:end' with pure digit offsets, e.g. mapping='0' or mapping='0:8'.
  2. Replace dash ranges ('0-8') with colon ranges ('0:8'); end offset is exclusive per decode logic.
  3. Remove the mapping property to accept the default offset '0'.
  4. Verify offsets are non-negative integers and match the record's byte layout.

Example fix

// before: unsupported range syntax
-- flags BIGINT WITH (data_format='INT', mapping='0-4')
// after
-- flags BIGINT WITH (data_format='INT', mapping='0:4')
Defensive patterns

Strategy: validation

Validate before calling

Pattern MAPPING = Pattern.compile("\\d+(?::\\d+)?");
void checkRawMapping(String mapping) {
  if (mapping != null && !MAPPING.matcher(mapping).matches())
    throw new IllegalArgumentException("invalid raw mapping (use 'start' or 'start:end'): " + mapping);
}

Try / catch

try { stmt.execute(ddl); } catch (SQLException e) { if (e.getMessage().contains("invalid mapping format")) { rewriteMappingSyntax(); } else throw e; }

Prevention

When it happens

Trigger: Creating a raw-decoder column with mapping like '10-20', 'name', '-1', '0:abc', or an empty-but-present value; MAPPING_PATTERN.matches() fails and the constructor throws immediately.

Common situations: Users porting mappings from other connectors that use different syntax (dash ranges, field names); copy-paste with whitespace inside quotes; attempting named-field mapping that only JSON/Avro decoders support.

Related errors


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