apache/druid · error · IAE
Unable to parse timestamps with format
Error message
Unable to parse timestamps with format [%s]
What it means
TimestampParser.createTimestampParser builds a DateTimeFormatter from the configured format string; if the Joda-Time pattern is invalid or cannot be constructed, it throws IllegalArgumentException wrapping the cause with 'Unable to parse timestamps with format [<format>]'. This fails fast at parser construction, before any data is seen.
Solutions
- Correct the format string to valid Joda-Time syntax (e.g. "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
- Verify each token against the Joda-Time DateTimeFormat documentation
- Test the format with DateTimeFormat.forPattern(format) in isolation before wiring it into ingestion
- If the data is actually numeric timestamps, use createNumericTimestampParser instead
Example fix
// before
TimestampParser.createTimestampParser("%Y-%m-%d %H:%M:%S") // strftime-style: throws
// after
TimestampParser.createTimestampParser("yyyy-MM-dd HH:mm:ss") Defensive patterns
Strategy: validation
Validate before calling
try {
org.joda.time.format.DateTimeFormat.forPattern(format);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid timestamp format: " + format, e);
} Type guard
boolean isValidJodaFormat(String format) {
try { org.joda.time.format.DateTimeFormat.forPattern(format); return true; }
catch (Exception e) { return false; }
} Try / catch
try {
Function<Number, DateTime> p = TimestampParser.createTimestampParser(format);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("Fix timestamp format in config: " + format, e);
} Prevention
- Use Joda-Time pattern syntax, not SimpleDateFormat or strftime tokens
- Verify tokens like yyyy vs YYYY, HH vs hh against Joda docs
- Unit-test the format against real timestamp samples before ingestion
- Use numeric timestamp parsing when the data is epoch values
When it happens
Trigger: Calling createTimestampParser(String format) with a format string that Joda-Time's DateTimeFormat cannot parse (bad pattern letters, invalid literals).
Common situations: Typos in format tokens (e.g. 'YYY' vs 'yyyy', 'hh' vs 'HH'); copying SimpleDateFormat patterns that differ from Joda syntax; formats pasted from other systems like Python strftime; null or empty format handled earlier but invalid syntax reaches here.
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
- Adjacent intervals are not sorted
- Element of intervals is null
- Empty list of intervals
- Encountered row with timestamp
- Protobuf message could not be parsed
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/ed48cb746a6d3eb7.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/java/util/common/parsers/TimestampParser.java:97
Preconditions.checkArgument(!Strings.isNullOrEmpty(input), "null timestamp");
return numericFun.apply(Long.parseLong(ParserUtils.stripQuotes(input)));
};
} else if ("ruby".equalsIgnoreCase(format)) {
final Function<Number, DateTime> numericFun = createNumericTimestampParser(format);
return input -> {
Preconditions.checkArgument(!Strings.isNullOrEmpty(input), "null timestamp");
return numericFun.apply(Double.parseDouble(ParserUtils.stripQuotes(input)));
};
} else {
try {
final DateTimes.UtcFormatter formatter = DateTimes.wrapFormatter(DateTimeFormat.forPattern(format));
return input -> {
Preconditions.checkArgument(!Strings.isNullOrEmpty(input), "null timestamp");
return formatter.parse(ParserUtils.stripQuotes(input));
};
}
catch (Exception e) {
throw new IAE(e, "Unable to parse timestamps with format [%s]", format);
}
}
}
public static Function<Number, DateTime> createNumericTimestampParser(
final String format
)
{
if ("posix".equalsIgnoreCase(format)) {
return input -> DateTimes.utc(TimeUnit.SECONDS.toMillis(input.longValue()));
} else if ("micro".equalsIgnoreCase(format)) {
return input -> DateTimes.utc(TimeUnit.MICROSECONDS.toMillis(input.longValue()));
} else if ("nano".equalsIgnoreCase(format)) {
return input -> DateTimes.utc(TimeUnit.NANOSECONDS.toMillis(input.longValue()));
} else if ("ruby".equalsIgnoreCase(format)) {
return input -> DateTimes.utc(Double.valueOf(input.doubleValue() * 1000).longValue());
} else {
return input -> DateTimes.utc(input.longValue());View on GitHub (pinned to 9b90983fd2)