适用版本: 7.x-8.9
1. 错误异常的基本描述 #
Failed to get id [id] with includes/excludes set 表示 Elasticsearch 已经取到了文档的 _source,但在按照 includes/excludes 规则做字段过滤时失败。相比普通的 Failed to get id [id],这个异常更明确地指向 _source 过滤阶段,而不是 stored fields 初始定位阶段。
从日志片段可见,异常发生在 XContentFieldFilter.newFieldFilter(...).apply(source, null)。这说明问题出在 _source 的过滤与重写过程,而不是文档定位过程。
常见现象 #
- 只有带
_source_includes、_source_excludes或等价参数的 Get 请求失败,返回500内部服务器错误。 - 不带 source 过滤时读取正常(如
GET /index/_doc/id不加参数),带过滤条件时却失败。 - 使用
_source参数指定返回的字段时触发异常,例如GET /index/_doc/id?_source_includes=field1,field2。 - 日志中常伴随
_source解析、内容转换或 I/O 相关异常。 - 如果是批量查询(
_mget),只有部分指定了 source 过滤的文档会失败。
典型报错与异常栈 #
常见日志形态通常类似下面这样:
ElasticsearchException: Failed to get id [abc123] with includes/excludes set
Caused by: java.io.IOException: read past EOF
at org.elasticsearch.common.xcontent.XContentFieldFilter...
或者 _source 解析异常:
ElasticsearchException: Failed to get id [abc123] with includes/excludes set
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character
at com.fasterxml.jackson.core.JsonParser...
或者内容截断:
ElasticsearchException: Failed to get id [abc123] with includes/excludes set
Caused by: java.io.EOFException: null
at org.elasticsearch.common.xcontent.XContentHelper...
2. 为什么会发生这个错误 #
Failed to get id [id] with includes/excludes set 的根因是"在 Get 请求中,_source 内容过滤过程失败"。Elasticsearch 需要先获取完整的 _source,然后根据 includes/excludes 规则进行字段过滤;如果 _source 内容本身有问题,或者过滤过程出现异常,就会抛出此异常。
常见原因通常包括:
_source内容损坏:文档的_sourceJSON 内容损坏、截断或不是可正常解析的 XContent 格式。_source格式异常:写入时数据格式有问题(如非 UTF-8 编码、非法 JSON 字符),导致解析失败。- includes/excludes 规则复杂叠加:过滤规则与实际文档结构复杂叠加(如嵌套对象、数组),触发过滤阶段异常。
- 底层 I/O 问题:节点在处理
_source时遭遇底层 I/O 问题,如磁盘读取失败、文件句柄异常。 - 大文档问题:
_source特别大的文档在过滤时可能触发内存或缓冲区问题。 - 字段路径不存在:includes/excludes 中指定的字段路径在文档中不存在,且过滤逻辑对此处理不当。
- 历史数据问题:某些异常文档内容在无过滤时还能原样返回,但一旦需要解析过滤就会暴露问题。
3. 如何排查和解决这个异常和解决这个异常 #
建议按"先复现问题、再检查 _source、后优化过滤规则"的顺序处理:
复现问题:分别测试"无 includes/excludes"和"有 includes/excludes"的 Get 请求,确认问题触发条件。
# 不带过滤,查看是否能正常获取 curl -X GET "localhost:9200/my_index/_doc/my_id?pretty" # 带过滤,查看是否触发异常 curl -X GET "localhost:9200/my_index/_doc/my_id?_source_includes=field1,field2&pretty"检查 _source 内容:抓取目标文档原始
_source,确认其内容是否完整和合法。# 获取原始 _source curl -X GET "localhost:9200/my_index/_doc/my_id?_source=true" > source.json # 验证 JSON 格式 cat source.json | jq . # 如果 jq 解析失败,说明 JSON 有问题简化过滤规则:逐步缩小触发异常的字段路径,定位是哪个字段过滤导致的问题。
# 逐个字段测试 curl -X GET "localhost:9200/my_index/_doc/my_id?_source_includes=field1" curl -X GET "localhost:9200/my_index/_doc/my_id?_source_includes=field2"检查节点日志:结合节点日志确认是
_source解析异常还是底层 I/O 异常。# 查看相关错误日志 grep -r "Failed to get id.*includes/excludes" /var/log/elasticsearch/ grep -r "XContentFieldFilter" /var/log/elasticsearch/检查文档大小:确认文档是否过大,导致过滤时出现问题。
# 查看文档大小(通过 _size 字段,需要 mapper-size 插件) curl -X GET "localhost:9200/my_index/_doc/my_id?stored_fields=_size"检查历史数据:如果问题只发生在少量旧文档上,重点检查历史写入链路和数据修复记录。
排查时需要注意的问题 #
- 如果
_source本身损坏,不带过滤时可能也能返回数据(只是内容有问题),但过滤时需要解析完整内容,所以会暴露问题。 - includes/excludes 支持通配符和路径表达式,复杂规则可能匹配到意外的字段,需要仔细检查。
- 对于大文档,过滤操作可能消耗较多内存,需要确保节点有足够资源。
4. 如何解决这个错误 #
常用修复思路 #
修复或删除损坏文档:对于
_source损坏的文档,可以尝试重新索引或删除。# 删除损坏的文档 curl -X DELETE "localhost:9200/my_index/_doc/my_id" # 重新索引(如果有原始数据) curl -X PUT "localhost:9200/my_index/_doc/my_id" -H 'Content-Type: application/json' -d' { "field1": "value1", "field2": "value2" } '简化过滤规则:修正 includes/excludes 表达式,避免对异常结构做深层过滤。
# 使用更简单的过滤规则 # 原来可能过于复杂:?_source_includes=obj1.*.field,obj2.nested[*].value # 改为更简单的:?_source_includes=field1,field2 curl -X GET "localhost:9200/my_index/_doc/my_id?_source_includes=field1,field2"重建索引:如果多个文档都有问题,考虑重建整个索引。
# 重建索引(跳过无法解析的文档) curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d' { "source": { "index": "old_index" }, "dest": { "index": "new_index" }, "conflicts": "proceed" # 跳过冲突文档 } '修复底层 I/O 问题:若底层 I/O 不稳定,先恢复节点与存储健康状态(参考
failed-to-get-id-id的处理方法)。禁用 source 过滤:作为临时解决方案,可以暂时不使用 source 过滤,或者改用
stored_fields参数。# 使用 stored_fields 代替 _source 过滤(需要字段设置为 store=true) curl -X GET "localhost:9200/my_index/_doc/my_id?stored_fields=field1,field2"
后续注意事项与推荐建议 #
- 在应用层对写入 Elasticsearch 的数据进行校验,确保
_source内容是合法的 JSON 格式。 - 对于重要索引,考虑在 mapping 中设置
_source的enabled为false(如果不需要原始_source),或者只存储必要的字段。 - 建立对大文档的监控,在文档大小异常增长时及时预警。
- 为
_source过滤操作配置适当的超时和内存限制,避免大文档导致节点内存压力。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看索引的文档样本、字段分布和
_source内容,帮助快速判断是特定文档问题还是系统性问题,并提供可视化的文档查看和编辑功能。 - INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测和流量治理,可以记录所有 Get 请求的详细日志,包括
_source过滤参数,帮助定位是请求参数问题还是数据问题,同时提供请求缓存功能减少重复的过滤操作。 - 建议将文档读取失败、source 过滤异常等指标统一接入监控面板,结合 INFINI Console 的告警功能,在文档质量问题频发时及时通知。
5. 小结 #
Failed to get id [id] with includes/excludes set 说明文档已经找到了,但 _source 过滤失败。排查时要把重点放在原始 _source 的健康状况和 includes/excludes 规则本身,而不是只看 ID 是否存在。大多数情况下,这个问题可以通过检查 _source 内容完整性、简化过滤规则和修复损坏文档来解决。
只要把数据校验、文档监控和过滤规则管理固定下来,大多数 _source 过滤类异常都可以被快速定位和恢复,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续防护。
相关错误 #
- failed-to-get-id-id-how-to-solve-this-elasticsearch-exception
- failed-to-get-type-type-and-id-id-with-includes-excludes-set-how-to-solve-this-elasticsearch-exception
- failed-to-get-binary-value-how-to-solve-this-elasticsearch-exception
- failed-to-parse-content-to-map-how-to-solve-this-elasticsearch-exception
- document-parse-exception-how-to-solve-this-elasticsearch-exception
参考文档 #
- Elasticsearch Get API 官方文档
- Elasticsearch _source 参数官方文档
- Elasticsearch 文档 API 官方文档
- INFINI Console 文档
- INFINI Gateway 文档
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
} else if (fetchSourceContext.includes().length > 0 || fetchSourceContext.excludes().length > 0) {
try {
source = XContentFieldFilter.newFieldFilter(fetchSourceContext.includes(); fetchSourceContext.excludes())
.apply(source; null);
} catch (IOException e) {
throw new ElasticsearchException("Failed to get id [" + id + "] with includes/excludes set"; e);
}
}
} return new GetResult(





