适用版本: 7.2-7.15
1. 错误异常的基本描述 #
analyzer [xxx] contains filters [yyy] that are not allowed to run in [mode] mode 是 Elasticsearch 在索引映射(mapping)或索引模板中配置自定义分析器时抛出的异常。该错误的核心含义是:分析器中引用了不允许在当前分析模式下运行的 token filter。
Elasticsearch 从 7.x 开始对分析器的运行模式(AnalysisMode)进行了严格区分,某些 token filter 只能在特定模式下运行(如索引时 INDEX 模式或搜索时 SEARCH 模式)。当分析器配置中混入了不匹配的过滤器时,就会触发此异常。
常见现象 #
- 创建索引、更新映射或应用索引模板时,Elasticsearch 返回 HTTP
400 Bad Request,并附带MapperException异常信息。 - 集群日志中出现类似以下报错:
MapperException: analyzer [my_analyzer] contains filters [synonym, keyword_repeat]
that are not allowed to run in index mode.
- 索引创建失败,导致依赖该索引的数据写入任务全部报错,影响业务正常运行。
- 如果使用动态模板或索引生命周期管理(ILM),相关索引滚动操作也会失败。
典型报错与异常栈 #
org.elasticsearch.index.mapper.MapperException: analyzer [my_analyzer] contains filters
[synonym] that are not allowed to run in index mode.
at org.elasticsearch.index.analysis.CustomAnalyzer.checkAnalysisMode(CustomAnalyzer.java)
at org.elasticsearch.index.analysis.CustomAnalyzer.build(CustomAnalyzer.java)
at org.elasticsearch.index.analysis.AnalysisRegistry.buildCustomAnalyzer(AnalysisRegistry.java)
2. 为什么会发生这个错误 #
Elasticsearch 的 token filter 分为三种运行模式,由 AnalysisMode 枚举定义:
| 模式 | 说明 | 典型 filter 示例 |
|---|---|---|
INDEX | 仅允许在索引写入阶段运行 | trim、lowercase、asciifolding |
SEARCH | 仅允许在搜索分析阶段运行 | synonym(搜索时同义词)、keyword_repeat |
ALL | 索引和搜索阶段均可运行 | standard、icu_normalizer |
当自定义分析器引用了 AnalysisMode 与当前使用场景不匹配的 filter 时,就会触发此异常。常见原因包括:
- 混淆了索引分析与搜索分析的职责:将只能在搜索时使用的 filter(如
synonym的搜索变体)配置到了索引分析器中。 - 直接复制了示例配置但未理解模式限制:从官方文档或社区复制的分析器配置,其 filter 列表在当前版本中已被限制运行模式。
- 插件提供的 filter 模式不兼容:第三方分析插件(如 ICU、SmartCN、IK)升级后,某些 filter 的
AnalysisMode发生了变更。 - 索引分析器与搜索分析器配置不对称:
analyzer与search_analyzer各自引用了不合规的 filter 组合。
3. 如何排查这个异常 #
建议按以下顺序定位问题根因:
3.1 提取完整报错信息 #
首先从 Elasticsearch 日志或 API 响应中提取完整的异常信息,重点关注:
- 分析器名称(
analyzer [xxx]) - offending filter 列表(
contains filters [yyy]) - 当前模式(
not allowed to run in [mode] mode)
3.2 检查索引映射或模板配置 #
使用以下 API 查看当前生效的分析器配置:
# 查看索引的 mapping 设置
GET /your_index/_settings
# 查看索引模板
GET /_index_template/your_template
# 查看组件模板(如果使用了可组合模板)
GET /_component_template/your_component_template
重点检查 settings.analysis.analyzer.<analyzer_name>.filter 字段,列出所有引用的 filter 名称。
3.3 验证每个 filter 的运行模式 #
通过 _analysis/analyze API 或查阅官方文档,确认每个 filter 支持的 AnalysisMode:
# 测试 filter 是否在当前模式下可用
POST /_analyze
{
"analyzer": "your_analyzer_name",
"text": "测试文本"
}
如果返回同样的异常,则说明分析器配置本身有问题。
4. 如何解决这个错误 #
4.1 移除不合规的 filter #
最直接的修复方式是:从分析器的 filter 列表中移除报错的 filter,或将其替换为同样功能但支持当前模式的替代 filter。
修复前(错误配置):
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "synonym"]
}
}
}
}
}
修复后(正确配置):
{
"settings": {
"analysis": {
"analyzer": {
"my_index_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase"]
},
"my_search_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "synonym"]
}
}
}
},
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "my_index_analyzer",
"search_analyzer": "my_search_analyzer"
}
}
}
}
4.2 为索引和搜索分别配置分析器 #
如果某个 filter 只能在搜索时使用(如搜索时同义词),正确的做法是为字段分别设置 analyzer(索引时)和 search_analyzer(搜索时),如上方示例所示。
4.3 重建已受影响的索引 #
如果索引已经创建失败,需要先清理再重建:
# 删除创建失败的索引
DELETE /your_index
# 修正 settings 后重新创建
PUT /your_index
{
"settings": { ... },
"mappings": { ... }
}
5. 如何预防此类问题 #
配置规范建议 #
- 索引/搜索职责分离:始终为复杂的分析需求分别定义
analyzer和search_analyzer,避免将所有 filter 堆砌在同一个分析器中。 - 在测试环境验证:任何自定义分析器配置在应用到生产环境前,必须先在测试环境通过
_analyzeAPI 验证。 - 显式声明 filter 顺序:filter 的执行顺序影响分析结果,在配置中显式列出并注释每个 filter 的用途,便于后续维护。
版本升级注意事项 #
- 从 6.x 升级到 7.x 时,
AnalysisMode的校验逻辑被引入,此前能正常工作的分析器配置可能在升级后报错。升级前务必在测试环境全量验证自定义分析器配置。 - 第三方分析插件(IK、SmartCN、ICU 等)升级后,建议查阅其 Release Notes 中关于
AnalysisMode的变更说明。
6. 借助 INFINI 产品提升排障效率 #
- INFINI Console 适合查看集群健康度、索引配置、分析器设置及错误趋势,帮助快速判断异常是配置问题还是运行时问题。
- INFINI Gateway 适合部署在 Elasticsearch 前面做请求观测、限流与缓存,在索引创建失败的场景下可以快速定位是哪个请求体触发了异常,并支持对高频失败请求进行熔断保护。
7. 小结 #
analyzer name contains filters that are not allowed to run in [mode] mode 的本质是分析器配置中引用了与当前运行模式不兼容的 token filter。通过理解 AnalysisMode 的三种模式(INDEX / SEARCH / ALL),并将索引分析与搜索分析的职责明确分离,可以从根本上避免此类问题。
建议在分析器配置变更时,始终通过 _analyze API 进行验证,并结合 INFINI Console 和 INFINI Gateway 建立持续的可观测性,缩短从发现问题到定位根因的时间。
相关错误 #
- unknown-predicate:未知的predicate
- unsupported-join-key:不支持的join key
- query-shard-exception:查询分片异常
- mapper-parsing-exception:映射解析异常
- illegal-argument-exception:非法参数异常
附:日志上下文 #
以下为 Elasticsearch 源码中抛出此异常的相关逻辑,便于深入理解触发条件:
AnalysisMode filterMode = tokenFilter.getAnalysisMode();
if (filterMode != AnalysisMode.ALL && filterMode != mode) {
offendingFilters.add(tokenFilter.name());
}
}
throw new MapperException("analyzer [" + name + "] contains filters " + offendingFilters
+ " that are not allowed to run in " + mode.getReadableName() + " mode.");
} else {
throw new MapperException(
"analyzer [" + name + "] contains components that are not allowed to run in "
+ mode.getReadableName() + " mode.");
}





