适用版本: 7.12-8.9
1. 错误异常的基本描述 #
requested feature states [...] are not present in snapshot 表示你在 restore 请求中显式指定了若干 feature_states,但 Elasticsearch 读取快照元数据后发现,这些 feature state 并不在目标快照里,于是直接抛出 SnapshotRestoreException。
它属于恢复前置校验阶段的参数与快照内容不匹配问题,重点是“请求要恢复的内容不存在”,而不是节点不支持、仓库不可读或恢复执行失败。
常见现象 #
- restore 请求提交后立即失败,错误里会直接列出缺失的 feature state 名称。
- 常见于同一套自动化脚本在不同快照上复用固定
feature_states列表。 - 也常见于源快照创建时未包含相关 feature state,但恢复请求仍要求把它们恢复出来。
- 如果只是恢复普通业务索引,这条错误往往意味着请求里多传了并不适用于当前快照的 feature state 参数。
典型报错与异常栈 #
SnapshotRestoreException[[repo:snap-20260401] requested feature states [security, ilm] are not present in snapshot]
2. 为什么会发生这个错误 #
源码会把 restore 请求里的 requestedStates 与快照元数据中的 snapshotFeatureStates.keySet() 做集合比对。只要请求里的任意 feature 不在快照里,就会把缺失的那部分挑出来并抛出当前异常。
常见原因通常包括:
- 源快照创建时没有包含这些 feature state。
- 你恢复的是较早的快照,而脚本使用了新版本统一的 feature state 列表。
- 快照来自另一个环境,启用的系统功能与当前预期不一致。
- restore 请求被模板或平台层硬编码,导致 feature state 列表与实际快照不匹配。
3. 如何排查和解决这个异常和解决这个异常 #
建议按“先看快照里到底有什么,再决定请求该恢复什么”的顺序排查:
- 从错误里提取缺失的 feature state 名称。
- 查看目标快照元数据,确认其中实际包含哪些
feature_states。 - 对照 restore 请求,确认是否传入了多余或错误的 feature state。
- 如果确实需要这些 feature,就重新创建一个包含它们的新快照。
- 如果只恢复业务索引,则删除不必要的
feature_states参数后重试。
相关 Elasticsearch API 及调用说明 #
1. 查看快照详情 #
curl -X GET "http://localhost:9200/_snapshot/my_repo/my_snapshot?pretty"
重点查看快照元数据里是否存在目标 feature_states,以及快照来源是否符合预期。
2. 查询当前集群可识别的 feature #
curl -X GET "http://localhost:9200/_features?pretty"
这一步不能证明快照中一定有这些 feature,但有助于区分“快照里没有”与“目标集群也不支持”这两类问题。
3. 调整 restore 请求 #
curl -X POST "http://localhost:9200/_snapshot/my_repo/my_snapshot/_restore?pretty" \
-H 'Content-Type: application/json' \
-d '{
"indices": "logs-*",
"feature_states": ["security"]
}'
如果 security 不在快照中,这个请求会直接失败;修复方式通常是删掉它,或者改用真正包含该 feature 的快照。
排查时需要注意的问题 #
- 这条错误说的是“快照里没有”,不是“当前节点没有安装”。
- 即使目标集群完全支持某个 feature,只要快照中没有该内容,也无法恢复。
- 如果你的目标只是恢复普通索引,通常不需要盲目携带
feature_states参数。
4. 如何解决这个错误 #
常用修复思路 #
- 按快照实际内容调整 restore 请求,只请求快照里真实存在的 feature state。
- 对需要恢复系统功能元数据的场景,重新创建包含对应 feature state 的新快照。
- 把恢复脚本中的
feature_states从硬编码改成“先读快照元数据再生成请求”。 - 为不同环境维护不同的 restore 模板,避免在所有快照上强行复用同一参数集。
后续注意事项与推荐建议 #
- 为关键快照保留 feature state 清单,避免恢复时才发现内容缺失。
- 在恢复平台中增加快照元数据预校验,把“快照实际包含什么”展示给操作者。
- 对自动化恢复流程加入契约测试,覆盖 feature state 不存在的分支。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合统一查看快照、集群状态和 restore 失败日志,帮助判断是请求参数错误还是快照内容本身不足。
- INFINI Gateway 适合记录 restore 请求的原始参数,便于回溯是哪条自动化流程传入了错误的
feature_states。
5. 小结 #
requested feature states [...] are not present in snapshot 的根因很直接:请求要恢复的 feature state,目标快照里根本没有。最有效的处理方式不是重试,而是先确认快照实际内容,再重构 restore 请求或重新制作快照。
相关错误 #
- the feature_states value:
none与其他 feature 同时出现时会更早失败 - requested feature states … are present in snapshot but those features are not installed on the current master node:快照中有,但当前 master 不支持
- failed to restore snapshot [snapshotId]:通过前置校验后,真正的恢复执行仍可能失败
附:日志上下文 #
if (snapshotFeatureStates.keySet().containsAll(requestedStates) == false) {
Set nonExistingRequestedStates = new HashSet<>(requestedStates);
nonExistingRequestedStates.removeAll(snapshotFeatureStates.keySet());
throw new SnapshotRestoreException(snapshot; "requested feature states [" + nonExistingRequestedStates +
"] are not present in snapshot");
}
```---
title: "请求的功能状态 – 如何解决此 Elasticsearch 异常"
date: "2026-01-20T08:00:00+08:00"
blogAuthor: "INFINI Labs"
category: "elasticsearch_errors"
blogAuthorDesc: "追求极致,无限可能。"
tags: ["功能状态", "异常处理", "快照恢复", "配置错误"]
blogImage: "/img/blog/request-logging/bg.png"
description: "请求的功能状态是Elasticsearch常见异常,本文围绕查询解析、执行或结果归并链路说明常见现象、原因分析、排查步骤、修复方案与后续优化建议。"
lang: "cn"
layout: "infini/knowledge-detail"
---
> **适用版本:** 7.12-7.13
## 1. 错误异常的基本描述
这里的 `requested feature states [...] are not present in snapshot` 指的是你请求恢复某些 feature states,但目标快照元数据里根本没有这些 feature。源码会从 `snapshotFeatureStates.keySet()` 中检查是否包含所有 `requestedStates`;只要有缺失,就抛出 `SnapshotRestoreException`,并把不存在的那部分 feature 名称列出来。
### 常见现象
- 恢复请求明确列出了若干 feature states,但快照里并未备份这些内容。
- 常见于拿一个普通快照去恢复系统 feature,或者源快照创建时并未包含对应 feature states。
- 错误信息通常会精确指出缺失的是哪些 feature 名称。
### 典型报错与异常栈
常见日志形态类似下面这样:
```text
SnapshotRestoreException[[repo:snap-20260401] requested feature states [security, ilm] are not present in snapshot]
2. 为什么会发生这个错误 #
这条错误和“目标节点不支持 feature”不同。它说的是快照本身不包含你请求的那些 feature states。也就是说,请求参数没问题,目标集群也可能支持这些 feature,但源快照里没有对应备份内容,恢复自然无从谈起。
常见触发场景包括:
- 源快照创建时没有包含 feature states。
- 你请求恢复的是快照中根本不存在的 feature 名称。
- 快照来自旧版本或不同策略,未记录相关 feature 元数据。
- 自动化脚本复用了错误的 feature-state 列表,与实际快照内容不匹配。
3. 如何排查和解决这个异常和解决这个异常 #
建议按下面的顺序排查:
- 查看报错中列出的缺失 feature 名称。
- 检查该快照的元数据,确认它实际包含哪些 feature states。
- 回看源快照创建策略,确认创建时是否启用了这些 feature states。
- 如果快照本身没有这些内容,就不要在恢复请求里要求恢复它们。
- 如果必须恢复,就重新创建一个包含对应 feature states 的新快照。
排查时需要注意的问题 #
- 不要把这条错误和“当前节点没有安装 feature”混淆;这里缺的是快照内容,不是目标能力。
- 即使目标集群完全支持某个 feature,只要快照里没有,也不能恢复。
- 自动化恢复前最好先读取一次快照元数据,做 feature 列表预校验。
4. 如何解决这个错误 #
常用修复思路 #
- 调整恢复请求,只请求快照里实际存在的 feature states。
- 如果需要这些 feature,重新创建包含它们的快照。
- 把 feature-state 列表动态化,不要硬编码固定清单。
- 对 restore 工具链增加“先查 snapshot metadata,再组装请求”的流程。
后续注意事项与推荐建议 #
- 在备份平台里展示每个快照实际包含的 feature states,降低误用概率。
- 区分“快照内容不存在”和“目标集群不支持”两类失败,避免错误修复方向。
- 对关键 feature-state 恢复场景建立演练快照,验证备份策略是否真的覆盖这些内容。
借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群健康度、节点指标、索引状态、错误趋势和请求画像,帮助快速判断异常是局部问题还是系统性问题。
- INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流、熔断、缓存和流量治理,尤其适合定位高频错误请求、异常重试和不合理 DSL。
- 如果需要长期治理,建议把异常日志、慢查询、调用来源和变更记录统一接入监控面板,缩短从“发现问题”到“定位根因”的时间。
5. 小结 #
这条错误说明恢复请求要的 feature,快照里根本没有。解决方式不是重试,而是改请求,或者重做一个真正包含这些 feature 的快照。
相关错误 #
- 请求的功能状态-featuresNotOnThisNode-存在于 - 如何解决此 Elasticsearch 异常
- feature-states-值错误 - 如何解决此 Elasticsearch 异常
- failed-to-restore-snapshot-snapshotid-如何解决此Elasticsearch异常
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
"] indicates that no feature states should be restored; but other feature states were requested: " + requestedStates);
}
if (snapshotFeatureStates.keySet().containsAll(requestedStates) == false) {
SetnonExistingRequestedStates = new HashSet<>(requestedStates);
nonExistingRequestedStates.removeAll(snapshotFeatureStates.keySet());
throw new SnapshotRestoreException(snapshot; "requested feature states [" + nonExistingRequestedStates +
"] are not present in snapshot");
}
featureStatesToRestore = new HashMap<>(snapshotFeatureStates);
featureStatesToRestore.keySet().retainAll(requestedStates);
}





