Elasticsearch 报错:index read-only / allow delete (api) 深度解析与解决方案
ClusterBlockException[index [.monitoring-es-7-2025.11.12] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]]

🚨 Elasticsearch 报错:index read-only / allow delete (api) 深度解析与解决方案
💡 关键词:Elasticsearch、磁盘空间不足、监控索引、只读状态
一、问题背景
在一次 Node.js 项目运行过程中,我们的 Elasticsearch 集群突然在日志中疯狂刷出警告:
"message": "unexpected error while indexing monitoring document",
"stacktrace": ["org.elasticsearch.xpack.monitoring.exporter.ExportException: ClusterBlockException[index [.monitoring-es-7-2025.11.12] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];]"
]
Kibana 监控页面无法更新,ES 指标面板停止刷新。
但奇怪的是,我们清理了磁盘空间后,问题仍然存在。
二、问题现象
执行 GET _cat/indices?v,可以看到 .monitoring-* 索引状态为 green,但日志仍不断报:
index [.monitoring-es-7-2025.11.12] blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
即使空间已经恢复,Elasticsearch 仍然拒绝对这些索引写入。
三、问题根因分析
1️⃣ Elasticsearch 的自动保护机制
当磁盘使用率超过阈值(默认 95%),ES 会自动触发保护机制:
index.blocks.read_only_allow_delete = true
意思是:
• 索引变为只读;
• 只允许删除(防止磁盘被完全写满导致崩溃)。
这是一种「自我保护」,以防止数据写满磁盘导致节点宕机。
2️⃣ 清理空间 ≠ 自动解除锁定
即使你清理了磁盘空间,Elasticsearch 不会自动解锁索引。
这点经常让人误以为“磁盘问题还没解决”,其实只是索引状态没恢复。
3️⃣ 监控索引的特殊性
报错中的 .monitoring-es-* 和 .monitoring-kibana-* 属于 X-Pack Monitoring 模块。
Kibana、Metricbeat 等监控数据会持续往这些索引写入。
只要它们被锁定,就会持续抛出 “unexpected error while indexing monitoring document”。
四、解决步骤 ✅
- 查看索引只读状态
执行以下命令查看哪些索引被锁定:
GET _all/_settings?filter_path=**.blocks.read_only_allow_delete
你会看到类似输出:
{".monitoring-es-7-2025.11.12": {"settings": {"index.blocks.read_only_allow_delete": "true"}}
}
- 清理磁盘空间
- 解锁索引
解锁单个索引:
PUT .monitoring-es-7-2025.11.12/_settings
{"index.blocks.read_only_allow_delete": null
}
或者解锁所有索引(推荐):
PUT _all/_settings
{"index.blocks.read_only_allow_delete": null
}
- 验证结果
再次执行:
GET _cat/indices?v
监控索引恢复正常写入后,日志中的 FORBIDDEN/12 报错将停止。
- (可选)清理旧监控索引
这些 .monitoring-* 索引每天会自动创建一个新索引(按日期)。
可以清理过期数据节省空间:
DELETE .monitoring-es-7-2025.10*
DELETE .monitoring-kibana-7-2025.10*
或者在 elasticsearch.yml 中关闭自动监控:
xpack.monitoring.enabled: false
五、延伸:为什么清理磁盘后错误还在?
这是很多人困惑的点。
Elasticsearch 判断磁盘“安全”需要两个条件:
1. 实际磁盘使用率低于 cluster.routing.allocation.disk.watermark.low(默认 85%);
2. 索引解除只读状态。
即使你释放了空间,只要第 2 步没做,仍然会报 index read-only / allow delete (api)。
六、总结
| 问题 | 原因 | 解决 |
|---|---|---|
| 报错 FORBIDDEN/12 | 磁盘满导致索引只读 | PUT _all/_settings 解锁 |
| 清理磁盘仍报错 | ES 不会自动解锁索引 | 手动恢复只读状态 |
| .monitoring-* 报错 | Kibana/ES 自带监控无法写入 | 解锁或清理监控索引 |
| 日志持续警告 | 未清理旧索引 | 删除历史 .monitoring-* |
七、实战命令汇总
# 查看集群磁盘状态
GET _cluster/stats?human# 查看只读索引
GET _all/_settings?filter_path=**.blocks.read_only_allow_delete# 全量解锁
PUT _all/_settings
{"index.blocks.read_only_allow_delete": null
}# 删除旧监控索引
DELETE .monitoring-es-7-2025.10*
DELETE .monitoring-kibana-7-2025.10*
