适用版本: 5.6-7.x(typed API 已废弃,8.x 已移除)
1. 错误异常的基本描述 #
Failed to get type [type] and id [id] 出现在旧版带 type 的 Get API 路径中,表示 Elasticsearch 在通过 Lucene reader 读取该文档的 stored fields 时失败。它与 typeless 版本的 Failed to get id [id] 类似,但这里仍处于历史的 typed document 读取模型下,涉及 type 和 id 两个维度。
常见现象 #
- 旧版接口如
GET /index/type/id返回500内部服务器错误。 - 问题通常只影响少量文档或个别分片,其他文档可以正常读取。
- 日志里常带
IOException、reader 读取失败或段文件异常,例如read past EOF或Corrupt index。 - 如果是批量查询(
_mget)中使用 typed 格式,只有特定 type 和 id 的组合会失败。 - 在 Elasticsearch 7.x 中,虽然默认不推荐,但 typed API 仍然可用;在 8.x 中,type 已被完全移除,此错误不再出现(会返回不同的错误)。
典型报错与异常栈 #
常见日志形态通常类似下面这样:
ElasticsearchException: Failed to get type [my_type] and id [abc123]
Caused by: java.io.IOException: read past EOF
at org.apache.lucene.index.SegmentReader.document(SegmentReader.java:...)
或者段文件损坏:
ElasticsearchException: Failed to get type [_doc] and id [xyz789]
Caused by: java.io.IOException: Corrupt index
at org.apache.lucene.codecs.StoredFieldsReader...
或者文件句柄问题:
ElasticsearchException: Failed to get type [logs] and id [doc456]
Caused by: java.io.IOException: Too many open files
2. 为什么会发生这个错误 #
Failed to get type [type] and id [id] 的根因是"在旧版 typed Get 请求中,读取文档 stored fields 失败"。从日志片段看,异常发生在 docIdAndVersion.reader.document(docIdAndVersion.docId, fieldVisitor)。这一步直接从底层 reader 读取目标文档字段;只要字段文件、reader 或底层存储异常,就会包装成当前错误。
常见原因通常包括:
- 旧索引段文件损坏:历史 typed 索引的 Lucene 段文件(
.fdt、.fdx、.si等)损坏或数据不完整。 - 分片状态不稳定:分片正在恢复、迁移或关闭,导致 reader 状态异常或不一致。
- 底层存储瞬时不可用:磁盘故障、文件系统错误、网络存储(如 NFS)断开,导致 Lucene 读取失败。
- 节点资源异常:磁盘空间不足、文件句柄耗尽(too many open files)、I/O 等待过高。
- 索引升级遗留问题:从旧版本(如 5.x、6.x)升级到新版本(如 7.x)后,历史 typed 索引在升级过程中遗留了底层读取问题。
- type 相关兼容性问题:在版本迁移过程中,type 的处理逻辑可能发生变化,导致某些历史数据读取失败。
- 段合并异常:在段合并过程中,某些段文件被意外删除或覆盖,影响 typed 文档的读取。
3. 如何排查和解决这个异常和解决这个异常 #
建议按"先确认 API 版本、再定位影响范围、后检查存储健康"的顺序处理:
确认 API 版本:检查调用的是否是旧版 typed API 或内部兼容路径,考虑迁移到 typeless API。
# 旧版 typed API(不推荐) curl -X GET "localhost:9200/my_index/my_type/my_id" # 新版 typeless API(推荐) curl -X GET "localhost:9200/my_index/_doc/my_id"检查异常影响范围:确认问题是否只影响特定 type、特定文档或特定分片。
# 查看索引中的 type 分布(7.x 中通常只有 _doc) curl -X GET "localhost:9200/my_index/_mapping?pretty" # 尝试获取其他文档,确认是否只有特定文档失败 curl -X GET "localhost:9200/my_index/_doc/other_id"查看节点日志:从 Elasticsearch 节点日志中找到这个异常对应的底层
caused by。# 查看相关错误日志 grep -r "Failed to get type" /var/log/elasticsearch/ grep -r "IOException" /var/log/elasticsearch/ | tail -50检查分片状态:确认分片是否处于恢复、迁移、关闭或异常状态。
# 查看分片分配和状态 curl -X GET "localhost:9200/_cat/shards/my_index?v" # 查看未分配分片的原因 curl -X GET "localhost:9200/_cluster/allocation/explain?pretty"检查磁盘和文件系统:查看磁盘空间、I/O 状态和文件句柄使用情况。
# 检查磁盘空间 df -h # 检查磁盘 I/O 错误 dmesg | grep -i "error\|io\|ext4\|xfs" # 检查文件句柄使用 lsof -p $(pgrep -f elasticsearch) | wc -l检查索引升级历史:如果索引是从旧版本升级而来,确认是否存在旧索引长期遗留问题。
# 查看索引创建版本(通过 settings) curl -X GET "localhost:9200/my_index/_settings?pretty" | grep "version"
排查时需要注意的问题 #
- 这个错误出现在旧版 typed API 中,如果可能,建议迁移到 typeless API(去掉 URL 中的 type 部分)。
- 如果问题只出现在特定 type 上,可能是该 type 对应的数据有问题,需要重点检查。
- 对于历史 typed 索引,需要考虑是否值得修复,还是直接迁移到新索引(typeless)。
4. 如何解决这个错误 #
常用修复思路 #
迁移到 typeless API:如果使用的是 7.x 或更高版本,建议迁移到 typeless API,避免 typed API 的兼容性问题。
# 旧版 typed API(避免使用) curl -X GET "localhost:9200/my_index/my_type/my_id" # 新版 typeless API(推荐使用) curl -X GET "localhost:9200/my_index/_doc/my_id"通过副本恢复分片:如果主分片数据损坏,可以尝试分配副本分片来恢复。
# 尝试分配副本分片 curl -X POST "localhost:9200/_cluster/reroute" -H 'Content-Type: application/json' -d' { "commands": [ { "allocate_replica": { "index": "my_index", "shard": 0, "node": "target_node_name" } } ] } '重建索引:对历史 typed 索引,考虑重建为 typeless 索引,同时修复数据问题。
# 重建索引(从旧索引到新索引) curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d' { "source": { "index": "old_typed_index" }, "dest": { "index": "new_typeless_index" } } '从快照恢复:如果有快照备份,可以从快照恢复受损的索引。
# 从快照恢复索引 curl -X POST "localhost:9200/_snapshot/my_backup/snapshot_1/_restore" -H 'Content-Type: application/json' -d' { "indices": "my_index", "ignore_unavailable": true, "include_global_state": false } '删除损坏文档:如果只有个别文档损坏,可以尝试删除后重新索引。
# 删除损坏的文档(需要知道文档 ID) curl -X DELETE "localhost:9200/my_index/my_type/my_id"
后续注意事项与推荐建议 #
- 如果仍在使用 typed API(Elasticsearch 7.x),建议尽快迁移到 typeless API,为升级到 8.x 做准备。
- 对于历史 typed 索引,评估是否需要重建为 typeless 索引,避免后续升级风险。
- 定期监控磁盘空间、文件句柄和 I/O 等待指标,在资源耗尽前提前预警。
- 为重要索引配置至少 1 个副本分片,确保在主分片故障时可以快速恢复。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群的索引状态、分片分配、节点指标和错误趋势,帮助快速判断
Failed to get type [type] and id [id]是局部数据问题还是系统性存储问题,并提供可视化的索引管理和重建功能。 - INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测和流量治理,可以记录所有 Get 请求的详细日志,帮助定位是 typed API 问题还是数据问题,同时提供请求缓存功能减少重复的读取操作。
- 建议将索引健康状态、分片分配和存储层指标统一接入监控面板,结合 INFINI Console 的告警功能,在分片异常或存储故障时及时通知。
5. 小结 #
Failed to get type [type] and id [id] 是典型的旧版 typed get 底层读取异常。处理时既要看当前 I/O 和分片状态,也要考虑索引历史和版本兼容包袱。如果可能,建议迁移到 typeless API 并重建历史索引,从根本上避免 typed API 的兼容性问题。
只要把存储监控、副本策略和版本升级规划固定下来,大多数 typed API 读取类异常都可以被有效解决,也更容易通过 INFINI Console 和 INFINI Gateway 实现持续防护。
相关错误 #
- failed-to-get-type-type-and-id-id-with-includes-excludes-set-how-to-solve-this-elasticsearch-exception
- failed-to-get-id-id-how-to-solve-this-elasticsearch-exception
- failed-to-get-binary-value-how-to-solve-this-elasticsearch-exception
- failed-to-read-value-how-to-solve-this-elasticsearch-exception
- corrupt-index-how-to-solve-this-elasticsearch-exception
参考文档 #
- Elasticsearch Get API 官方文档
- Elasticsearch Removal of Types 官方文档
- Elasticsearch 索引快照官方文档
- INFINI Console 文档
- INFINI Gateway 文档
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
FieldsVisitor fieldVisitor = buildFieldsVisitors(storedFields; fetchSourceContext);
if (fieldVisitor != null) {
try {
docIdAndVersion.reader.document(docIdAndVersion.docId; fieldVisitor);
} catch (IOException e) {
throw new ElasticsearchException("Failed to get type [" + type + "] and id [" + id + "]"; e);
}
source = fieldVisitor.source(); // put stored fields into result objects
if (fieldVisitor.fields().isEmpty() == false) {





