适用版本: 6.8-7.5
1. 错误异常的基本描述 #
恢复快照时,Elasticsearch 不会直接把历史索引原样挂进当前集群,而是会先尝试把快照中的索引元数据升级到当前集群允许的最小兼容版本。如果升级过程抛异常,就会报 cannot restore index [index] because it cannot be upgraded。
常见现象 #
- 快照文件能识别,恢复动作也开始了,但在恢复某个索引时失败。
- 异常常见于跨大版本恢复、历史旧索引恢复到较新集群时。
- 日志中通常还能看到更底层的 mapping、setting 或版本兼容性异常。
典型报错与异常栈 #
SnapshotRestoreException: cannot restore index [logs-2018] because it cannot be upgraded
2. 为什么会发生这个错误 #
源码里在恢复前会调用 metaDataIndexUpgradeService.upgradeIndexMetaData(...)。只要索引元数据中存在当前版本无法自动升级的内容,例如过旧的创建版本、废弃 mapping 结构、不兼容 setting,就会在这里失败。
常见原因包括:
- 快照中的索引创建于过老版本,超出了目标集群支持的恢复兼容范围。
- 索引使用了当前版本已不支持的 mapping/type 结构。
- 某些索引设置在升级过程中无法转换。
- 从中间版本升级链路被跳过,导致直接跨越过多版本恢复。
3. 如何排查和解决这个异常和解决这个异常 #
- 先查看快照和索引的版本信息:
GET /_snapshot/{repository}/{snapshot}
- 查看异常链中的真实升级失败原因,通常比外层这条错误更具体。
- 确认目标集群版本与快照源索引版本是否满足官方恢复兼容矩阵。
- 如果是老旧索引,考虑先在中间兼容版本集群恢复,再 reindex 到新版本。
- 若问题出在 mapping/type 结构,优先采用中转集群重建索引而不是强行直接恢复。
排查时需要注意的问题 #
- 这不是仓库读取失败,而是“索引元数据升级失败”。
- 有时只有少数历史索引无法升级,其他新索引仍可恢复,不要把整个仓库都判定为不可用。
- 如果跨版本跨度大,直接恢复失败是预期保护行为,不是偶发异常。
4. 如何解决这个错误 #
常用修复思路 #
- 按官方兼容路径选择一个中间版本集群,先恢复旧索引再做 reindex。
- 对无法升级的历史索引,优先导出数据并在新集群重建映射。
- 在快照治理中尽量淘汰过旧索引,避免长期保留无法兼容的历史格式。
- 恢复前先做版本盘点,区分哪些索引可直接恢复,哪些需要中转升级。
相关 Elasticsearch API #
GET /_snapshot/{repository}/{snapshot}:查看快照内容与索引列表。GET /{index}/_settings:在源集群检查索引创建版本和配置。POST /_reindex:在中转版本中把旧索引重建到兼容格式。
借助 INFINI 产品提升排障效率 #
- INFINI Console 可帮助统一查看快照来源集群与目标集群的版本和索引资产。
- INFINI Gateway 可用于审计恢复请求的来源,避免错误地把不兼容索引持续恢复到新集群。
5. 小结 #
cannot restore index [index] because it cannot be upgraded 的重点不是恢复动作本身,而是恢复前的索引元数据升级失败。面对这类问题,通常需要回到版本兼容路径,必要时通过中转集群恢复并重建索引。
相关错误 #
- cannot restore partial index:恢复目标上已有不完整残留索引
- cannot restore index [renamedIndex] because an open index:恢复目标索引已存在且处于打开状态
- recover snapshot files cancelled:快照文件恢复过程被中断
- detected a corrupted repository index:仓库元数据已损坏
- failed to fetch index version after copying it over:分片复制后仍无法读取索引版本
附:日志上下文 #
try {
snapshotIndexMetaData = metaDataIndexUpgradeService.upgradeIndexMetaData(snapshotIndexMetaData,
minIndexCompatibilityVersion);
} catch (Exception ex) {
throw new SnapshotRestoreException(snapshot, "cannot restore index [" + index + "] because it cannot be upgraded", ex);
}





