prestodb/presto · error
INVALID_TABLE_PROPERTY
INVALID_TABLE_PROPERTY
Error message
Locality groups string is malformed. See documentation for proper format.
What it means
Thrown by AccumuloTableProperties.getLocalityGroups when the locality_groups table property string cannot be parsed. The format must be pipe-separated groups, each 'groupName:col1,col2,...' with exactly one colon per group. Any group segment that does not split into exactly two colon-delimited parts throws INVALID_TABLE_PROPERTY.
Source
Thrown at presto-accumulo/src/main/java/com/facebook/presto/accumulo/conf/AccumuloTableProperties.java:194
*/
public static Optional<Map<String, Set<String>>> getLocalityGroups(Map<String, Object> tableProperties)
{
requireNonNull(tableProperties);
@SuppressWarnings("unchecked")
String groupStr = (String) tableProperties.get(LOCALITY_GROUPS);
if (groupStr == null) {
return Optional.empty();
}
ImmutableMap.Builder<String, Set<String>> groups = ImmutableMap.builder();
// Split all configured locality groups
for (String group : PIPE_SPLITTER.split(groupStr)) {
String[] locGroups = Iterables.toArray(COLON_SPLITTER.split(group), String.class);
if (locGroups.length != 2) {
throw new PrestoException(INVALID_TABLE_PROPERTY, "Locality groups string is malformed. See documentation for proper format.");
}
String grpName = locGroups[0];
ImmutableSet.Builder<String> colSet = ImmutableSet.builder();
for (String f : COMMA_SPLITTER.split(locGroups[1])) {
colSet.add(f.toLowerCase(Locale.ENGLISH));
}
groups.put(grpName.toLowerCase(Locale.ENGLISH), colSet.build());
}
return Optional.of(groups.build());
}
public static Optional<String> getRowId(Map<String, Object> tableProperties)
{
requireNonNull(tableProperties);View on GitHub (pinned to 55bb57d202)
Solutions
- Rewrite the locality_groups value so every pipe-separated segment has exactly one colon: 'group1:colA,colB|group2:colC'.
- Use pipes between groups and commas between column names within a group - never commas between groups.
- Remove empty segments (trailing or duplicate pipes) from the string.
- Quote the property string in SQL so colons and pipes survive parsing.
- Check the Accumulo connector documentation for the exact expected format before re-running the DDL.
Example fix
-- before CREATE TABLE t (...) WITH (locality_groups='meta:foo:bar,stats:cnt'); -- after CREATE TABLE t (...) WITH (locality_groups='meta:foo,bar|stats:cnt');
Defensive patterns
Strategy: validation
Validate before calling
boolean validLocalityGroups(String s) {
if (s == null) return true;
return java.util.Arrays.stream(s.split("\\|", -1))
.allMatch(g -> g.split(":", -1).length == 2);
}
// call before CREATE TABLE: if (!validLocalityGroups(groupsStr)) throw new IllegalArgumentException("malformed locality_groups"); Type guard
boolean isWellFormedGroup(String group) {
String[] parts = group.split(":", -1);
return parts.length == 2 && !parts[0].isEmpty() && !parts[1].isEmpty();
} Try / catch
try {
createTableWithLocalityGroups(props);
} catch (PrestoException e) {
if (e.getErrorCode().getName().equals("INVALID_TABLE_PROPERTY")) {
// fix the locality_groups string: 'group1:colA,colB|group2:colC'
} else {
throw e;
}
} Prevention
- Always format locality groups as 'name:col1,col2|name2:col3' - pipes between groups, commas between columns, exactly one colon per group.
- Validate the string with a quick split check before embedding it in DDL.
- Quote the property value in SQL so separators are not mangled.
- Never leave a trailing or leading pipe in the property string.
When it happens
Trigger: CREATE TABLE ... WITH (locality_groups='...') where a group segment contains zero or multiple colons, e.g. 'grpA' (no colon), 'grpA:col1:col2' (two colons), an empty segment from a trailing pipe 'grpA:col1|', or groups separated by commas instead of pipes.
Common situations: Copy-pasting locality group config with the wrong separator; forgetting to quote the property string in SQL so a colon or pipe is misinterpreted; leaving a trailing/duplicate pipe producing an empty group; writing groups in the wrong order or with wrong delimiters.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/e500741f167eb76c.
Report an issue: GitHub.