ES protects itself: past the flood-stage disk watermark (95% by default) it blocks writes and marks indices read-only. Clear disk space and unlock the indices — in that order.
Defaults: 85% low (no new shards), 90% high (relocate shards), 95% flood (block writes, mark read-only). df -h on the data nodes shows where you stand.
Flood stage sets index.blocks.read_only_allow_delete=true; freeing disk does NOT auto-clear it on older versions — you must remove the setting.
curl -s localhost:9200/_cat/allocation?v && df -h /var/lib/elasticsearch
curl -s -XDELETE 'localhost:9200/logs-2025.05-*' # or use ILM/curator to prune automatically going forward
curl -s -XPUT localhost:9200/_all/_settings -H 'Content-Type: application/json' -d '{"index.blocks.read_only_allow_delete": null}'
# elasticsearch.yml: cluster.routing.allocation.disk.watermark.low: 85%, high: 90%, flood_stage: 93% (plus monitoring/alerting at ~80%)
Big wins: check _cat/indices?v sorted by store.size for forgotten debug indices; enable ILM rollover so time-series data prunes itself. On 7.4+ flood blocks usually auto-clear, but verify the setting is null after space frees — assuming is how outages repeat.
The read_only_allow_delete block often persists after space frees (version-dependent). Remove it explicitly with the _settings PUT shown above, then confirm with GET <index>/_settings.
Plan capacity so steady-state stays under the low watermark (85% default). Once you're tuning flood_stage upward instead of freeing space, you're borrowing an outage.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.