apache/druid · error · ParseException
Unable to parse row [%s]
Error message
Unable to parse row [%s]
What it means
parseToMap wraps all parsing work in a try/catch and rethrows any failure (bad group counts, field-name mismatches, value conversion problems) as a ParseException 'Unable to parse row [<input>]'. It is the generic catch-all for rows that RegexParser cannot convert to a field/value map, with the original exception attached as the cause.
Source
Thrown at processing/src/main/java/org/apache/druid/java/util/common/parsers/RegexParser.java:109
final Matcher matcher = compiled.matcher(input);
if (!matcher.matches()) {
throw new ParseException(input, "Incorrect Regex: %s . No match found.", pattern);
}
List<String> values = new ArrayList<>();
for (int i = 1; i <= matcher.groupCount(); i++) {
values.add(matcher.group(i));
}
if (fieldNames == null) {
setFieldNames(ParserUtils.generateFieldNames(values.size()));
}
return Utils.zipMapPartial(fieldNames, Iterables.transform(values, valueFunction));
}
catch (Exception e) {
throw new ParseException(input, e, "Unable to parse row [%s]", input);
}
}
@Override
public void setFieldNames(Iterable<String> fieldNames)
{
ParserUtils.validateFields(fieldNames);
this.fieldNames = Lists.newArrayList(fieldNames);
}
@Override
public List<String> getFieldNames()
{
return fieldNames;
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Inspect the ParseException cause (getCause()) to see the underlying failure
- Ensure the number of fieldNames matches the number of capture groups in the pattern
- Validate sample rows against both the regex and the value function before ingestion
- Add try/catch around parseToMap calls to log and skip unparseable rows instead of failing the batch
Example fix
// before
Map<String,Object> row = parser.parseToMap(line); // throws on bad row
// after
try {
Map<String,Object> row = parser.parseToMap(line);
} catch (ParseException e) {
log.warn(e, "Skipping unparseable row");
} Defensive patterns
Strategy: try-catch
Validate before calling
if (line == null || line.isEmpty()) {
throw new IllegalArgumentException("Empty input row");
} Try / catch
try {
return parser.parseToMap(line);
} catch (ParseException e) {
log.error(e.getCause(), "Failed to parse row [%s]", line);
throw e; // or skip, depending on pipeline policy
} Prevention
- Always inspect getCause() — this error wraps the real failure
- Keep fieldNames count aligned with the regex capture-group count
- Test rows end-to-end with the exact valueFunction configured
- Skip-and-log bad rows in ingestion pipelines to avoid full-batch failure
When it happens
Trigger: Any exception inside parseToMap after a successful regex match: e.g. zipMapPartial/Iterables.transform failing in the valueFunction, mismatch between number of captured groups and fieldNames, or malformed input causing downstream value parsing to fail.
Common situations: Field-name list shorter/longer than captured groups after setFieldNames; custom value function (e.g. timestamp parser) rejecting a captured value; input row subtly malformed even though the regex matched.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid segment granularity [%s]
- Incorrect Regex: %s . No match found.
- invalid value %s
- Emit called unexpectedly before service start
- unknown event type [%s]
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ec6dd56b1858208b.
Report an issue: GitHub.