适用版本: 6.8-8.11
1. 错误异常的基本描述 #
Invalid date received; ... 表示 Elasticsearch 在将输入文本转换为日期字面量时失败,常见于 Elasticsearch SQL 或 EQL 查询解析路径中。当 SQL 语句或表达式中的日期字符串无法被解析为有效的 java.time.LocalDate 对象时,底层会抛出 DateTimeParseException,外层再包装成 ParsingException 并抛出当前异常。
常见现象 #
- 执行 Elasticsearch SQL 查询时返回
400 Bad Request错误。 - 错误响应中通常包含
Invalid date received;开头的错误信息,后面跟随具体的解析失败原因。 - 在 Elasticsearch 服务日志中可以找到
ParsingException或DateTimeParseException相关堆栈。 - 使用 JDBC 客户端或通过 REST API 直接调用 SQL 接口时均可能触发该异常。
典型报错与异常栈 #
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Invalid date received; Text '2023-13-01' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13"
}
],
"type": "parsing_exception",
"reason": "Invalid date received; Text '2023-13-01' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13"
},
"status": 400
}
底层 Java 异常栈通常类似:
ParsingException: Invalid date received; Text '2023-13-01' could not be parsed
Caused by: java.time.format.DateTimeParseException: Text '2023-13-01' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 13
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:...
at org.elasticsearch.xpack.sql.parser.CaseInsensitiveLiteralsParser.asDateOnly(CaseInsensitiveLiteralsParser.java:...)
2. 为什么会发生这个错误 #
Invalid date received 异常的触发根因是日期文本不符合 yyyy-MM-dd 格式要求,或日期值本身非法。常见原因包括:
- 日期格式不匹配:传入的日期字符串不符合 ISO 标准格式
yyyy-MM-dd,例如使用了MM/dd/yyyy、dd-MM-yyyy等非预期格式。 - 日期值非法:日期中的年、月、日数值超出有效范围,例如第 13 个月、第 32 天、2 月 30 日等。
- 混入时间或时区信息:在只接受纯日期(date only)的位置传入了 datetime 或带时区的时间字符串,例如
2023-01-01T00:00:00Z。 - 空字符串或 null 值:SQL 查询中引用了空值或空字符串作为日期字面量。
- 字符编码或不可见字符:日期字符串前后包含空格、制表符、换行符或其他不可见字符,导致解析失败。
- SQL 生成逻辑缺陷:应用层动态拼接 SQL 时,日期变量未正确格式化,或变量替换后产生了畸形日期字符串。
3. 如何排查和解决这个异常和解决这个异常 #
建议按以下步骤进行排查:
获取完整错误信息:从 Elasticsearch 响应或日志中提取完整的异常信息,重点关注
Text '...'部分,确认具体是哪个日期字符串解析失败。确认日期格式要求:Elasticsearch SQL 引擎在解析日期字面量时,默认期望
yyyy-MM-dd格式。确认你的输入是否匹配该格式。检查 SQL 语句:如果是直接执行 SQL,检查 SQL 文本中所有的日期字面量;如果是应用生成 SQL,打印最终发给 Elasticsearch 的 SQL 语句。
验证日期值合法性:确认年、月、日在有效范围内(年:合理范围;月:1-12;日:1-28/29/30/31,取决于月份和闰年)。
排查字符污染:检查日期字符串是否包含不可见字符,可以使用
SELECT HEX(date_column)或在应用层打印字符串的字节表示。
排查命令示例 #
# 查看 Elasticsearch 日志中的日期解析错误
grep -r "Invalid date received" /var/log/elasticsearch/
# 使用 curl 直接测试 SQL 查询
curl -X POST "localhost:9200/_sql" -H "Content-Type: application/json" -d '{
"query": "SELECT * FROM my_index WHERE date_field = 2023-01-01"
}'
# 检查索引中日期字段的实际数据格式
curl -X GET "localhost:9200/my_index/_search" -H "Content-Type: application/json" -d '{
"size": 10,
"_source": ["date_field"],
"query": { "match_all": {} }
}'
4. 如何解决这个错误 #
常用修复思路 #
统一日期格式:确保所有日期字面量使用
yyyy-MM-dd格式。如果数据源使用其他格式,在传入 SQL 前进行转换。校验日期值合法性:在应用层对日期值做前置校验,确保月、日数值在有效范围内,避免 2 月 30 日等非法日期传入。
分离日期与时间:如果实际需要的是 datetime,应使用
CAST函数或明确指定 timestamp 类型,而不是将 datetime 字符串直接用作 date 字面量。清洗输入字符串:去除日期字符串前后的空格和不可见字符,防止解析失败。
使用参数化查询:避免直接拼接 SQL 字符串,使用 Elasticsearch SQL 的参数化方式或预处理方式传入日期值。
修复示例 #
-- 错误示例:格式不正确
SELECT * FROM orders WHERE order_date = '01/01/2023';
-- 正确示例:使用标准格式
SELECT * FROM orders WHERE order_date = '2023-01-01';
-- 使用 CAST 处理 datetime 转 date
SELECT * FROM orders WHERE CAST(order_timestamp AS DATE) = '2023-01-01';
// Java 应用层日期格式化示例
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String formattedDate = LocalDate.now().format(formatter);
// 使用 formattedDate 拼接 SQL 或作为参数传入
后续注意事项与推荐建议 #
- 在应用层建立日期格式化工具类,统一所有日期输出的格式,避免各处散落不同的日期格式处理逻辑。
- 对用户输入的日期做严格的格式校验和范围校验,在到达 Elasticsearch 之前就拦截非法输入。
- 如果业务需要支持多种日期格式,考虑在 Elasticsearch 端使用
DATE_PARSE函数进行显式转换,而不是依赖隐式解析。
借助 INFINI 产品提升排障效率 #
INFINI Console 可以查看 Elasticsearch 集群的 SQL 查询日志、错误趋势和慢查询记录,帮助快速定位哪些 SQL 语句产生了日期解析错误,以及这些语句的来源和频率。
INFINI Gateway 部署在 Elasticsearch 前面时,可以对 SQL 请求进行观测和审计,记录所有失败的 SQL 语句及其完整上下文,同时支持对日期格式进行正则校验和请求改写,在网关层拦截非法日期输入。
对于需要支持多种日期格式的业务场景,INFINI Gateway 的脚本过滤功能可以在请求到达 Elasticsearch 之前对日期字符串进行标准化处理,减少因日期格式问题导致的查询失败。
5. 小结 #
Invalid date received 是一个典型的 SQL 字面量解析异常,根因几乎总是日期文本格式或值不符合 yyyy-MM-dd 的要求。处理该异常时,应先从错误信息中提取具体的失败日期字符串,确认其格式和值是否合法,然后在应用层统一日期格式化逻辑。结合 INFINI Console 的查询审计和 INFINI Gateway 的请求治理能力,可以从根源上减少此类异常的发生。
相关错误 #
- invalid-timestamp-received-how-to-solve-this-elasticsearch-exception
- invalid-description-date-format-how-to-solve-this-elasticsearch-exception
- failed-to-parse-date-field-with-format-how-to-solve-this-elasticsearch-exception
- unknown-date-time-unit-id-how-to-solve-this-elasticsearch-exception
- operator-not-supported-for-date-math-how-to-solve-this-elasticsearch-exception
参考文档 #
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
try {
return new Literal(source, asDateOnly(string), SqlDataTypes.DATE);
} catch (DateTimeParseException ex) {
throw new ParsingException(source, "Invalid date received; {}", ex.getMessage());
}





