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
- Use 'start' or 'start:end' with pure digit offsets, e.g. mapping='0' or mapping='0:8'.
- Replace dash ranges ('0-8') with colon ranges ('0:8'); end offset is exclusive per decode logic.
- Remove the mapping property to accept the default offset '0'.
- 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
- Use only digit offsets with optional colon-separated end: '0', '0:8'.
- Never reuse mapping syntax from JSON/Avro decoders (field names) for raw columns.
- Unit-test your DDL generator against the (\d+)(?::(\d+))? pattern.
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
- invalid dataFormat '%s' for column '%s'
- DECODER_CONVERSION_NOT_SUPPORTED
- Wrong dataFormat '%s' specified for column '%s'; %s type imp
- DECODER_CONVERSION_NOT_SUPPORTED
- ACCUMULO_TABLE_EXISTS
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/c2fbf2ba7a46264f.
Report an issue: GitHub.