elastic/elasticsearch · error · RuntimeException
Invalid Mapping Rule : [{rule}]
Error message
Invalid Mapping Rule : [{rule}] What it means
WordDelimiterTokenFilterFactory.parseTypes converts each 'type_table' entry into a char->type mapping. Every rule must match the regex '(.*)\s*=>\s*(.*)\s*$' (i.e. 'lhs => rhs'). If Matcher.find() returns false, parseTypes throws RuntimeException (not IllegalArgumentException) with the offending rule. This indicates a structural problem — the rule lacks the '=>' separator at all.
Source
Thrown at modules/analysis-common/src/main/java/org/elasticsearch/analysis/common/WordDelimiterTokenFilterFactory.java:117
public static int getFlag(int flag, Settings settings, String key, boolean defaultValue) {
if (settings.getAsBoolean(key, defaultValue)) {
return flag;
}
return 0;
}
// source => type
private static final Pattern typePattern = Pattern.compile("(.*)\\s*=>\\s*(.*)\\s*$");
/**
* parses a list of MappingCharFilter style rules into a custom byte[] type table
*/
static byte[] parseTypes(Collection<String> rules) {
SortedMap<Character, Byte> typeMap = new TreeMap<>();
for (String rule : rules) {
Matcher m = typePattern.matcher(rule);
if (m.find() == false) {
throw new RuntimeException("Invalid Mapping Rule : [" + rule + "]");
}
String lhs = parseString(m.group(1).trim());
Byte rhs = parseType(m.group(2).trim());
if (lhs.length() != 1) throw new RuntimeException("Invalid Mapping Rule : [" + rule + "]. Only a single character is allowed.");
if (rhs == null) throw new RuntimeException("Invalid Mapping Rule : [" + rule + "]. Illegal type.");
typeMap.put(lhs.charAt(0), rhs);
}
// ensure the table is always at least as big as DEFAULT_WORD_DELIM_TABLE for performance
byte types[] = new byte[Math.max(typeMap.lastKey() + 1, WordDelimiterIterator.DEFAULT_WORD_DELIM_TABLE.length)];
for (int i = 0; i < types.length; i++) {
types[i] = WordDelimiterIterator.getType(i);
}
for (Map.Entry<Character, Byte> mapping : typeMap.entrySet()) {
types[mapping.getKey()] = mapping.getValue();
}
return types;
}View on GitHub (pinned to db6a809a66)
Solutions
- Reformat every type_table entry as "<chars> => <TYPE>" with a literal '=>'.
- Strip comment lines and stray punctuation from the list.
- Re-run the index/template create.
Example fix
// before "type_table": ["LOWER", "- => ALPHA"] // after "type_table": ["- => ALPHA", ". => DIGIT"]
Defensive patterns
Strategy: validation
Validate before calling
// Every type_table entry must match 'lhs => rhs'
static final java.util.regex.Pattern RULE = java.util.regex.Pattern.compile("(.*)\\s*=>\\s*(.*)\\s*$");
static List<String> badRules(List<String> typeTable) {
return typeTable.stream().filter(r -> !RULE.matcher(r).find()).toList();
} Prevention
- Lint type_table entries against the 'lhs => rhs' regex before applying.
- Keep type_table under version control and re-validate on every change.
When it happens
Trigger: Passing a type_table entry on a word_delimiter filter that does not contain '=>', e.g. "LOWER", "a,b,c", or a stray comment line.
Common situations: Hand-editing a type_table and forgetting the arrow; mis-pasting from documentation that used a different separator; carrying over an old Solr config with a different rule format.
Related errors
- Invalid Mapping Rule : [{rule}]. Only a single character is
- Invalid Mapping Rule : [{rule}]. Illegal type.
- Invalid escaped char in [{s}]
- failed to build synonyms from [{rules.origin}]
- Token filter [{name()}] cannot be used to parse synonyms
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/ca149407f9017d08.
Report an issue: GitHub.