This error occurs when Elasticsearch puts an index into read-only mode, typically due to low disk space or cluster settings. The index blocks write operations but allows deletions to free up space. You need to address the underlying disk space issue or adjust cluster settings to restore write access.
The "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]" error indicates that Elasticsearch has placed one or more indices into a read-only state. This is a protective mechanism that prevents data corruption when the cluster encounters critical conditions, most commonly low disk space. When Elasticsearch detects that a node's disk usage exceeds certain thresholds (default: 85% for low watermark, 90% for high watermark, 95% for flood stage), it automatically blocks write operations to indices on that node. The "allow delete (api)" part means that while indexing and update operations are blocked, delete operations are still permitted - this allows the system to free up space by deleting documents. This error protects your data by preventing writes that could fail due to insufficient disk space, which could lead to data corruption or cluster instability. The cluster will automatically remove the read-only block once sufficient disk space becomes available, but you may need to intervene manually in some cases.
First, examine the current disk usage and cluster health to understand the scope of the problem:
# Check cluster health with disk awareness
curl -X GET "localhost:9200/_cluster/health?pretty" -u "username:password"
# Check disk usage per node
curl -X GET "localhost:9200/_cat/allocation?v&pretty" -u "username:password"
# Detailed node stats including disk
curl -X GET "localhost:9200/_nodes/stats/fs?pretty" -u "username:password"
# Check which indices are blocked
curl -X GET "localhost:9200/_cluster/state?filter_path=metadata.indices.*.settings.index.blocks.*&pretty" -u "username:password"
# Get specific index settings to see blocks
curl -X GET "localhost:9200/my-index/_settings?pretty&flat_settings=true" -u "username:password"Look for:
- Disk usage percentages above 85% (low watermark), 90% (high watermark), or 95% (flood stage)
- Indices with "index.blocks.read_only_allow_delete" set to "true"
- Nodes with "disk.threshold_enabled: true" in their settings
If disk space is the issue, free up space by deleting old indices or documents:
# Delete old indices (be careful!)
curl -X DELETE "localhost:9200/old-index-*" -u "username:password"
# Use ILM (Index Lifecycle Management) to manage indices
curl -X GET "localhost:9200/_ilm/policy?pretty" -u "username:password"
# Force merge to reduce segment count and free space
curl -X POST "localhost:9200/my-index/_forcemerge?max_num_segments=1&pretty" -u "username:password"
# Clear cache (temporary relief)
curl -X POST "localhost:9200/my-index/_cache/clear?pretty" -u "username:password"
# Delete by query to remove old documents
curl -X POST "localhost:9200/my-index/_delete_by_query?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"query": {
"range": {
"@timestamp": {
"lt": "now-30d/d"
}
}
}
}
'Important: Monitor disk usage after each operation. Deleting indices provides immediate space, while force merge and cache clear provide temporary relief.
If you cannot immediately free enough disk space, you can adjust the disk watermark thresholds:
# Check current disk watermark settings
curl -X GET "localhost:9200/_cluster/settings?include_defaults=true&filter_path=**.disk.*&pretty" -u "username:password"
# Temporarily raise flood stage threshold (use with caution!)
curl -X PUT "localhost:9200/_cluster/settings?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.disk.watermark.flood_stage": "97%",
"cluster.routing.allocation.disk.watermark.high": "92%",
"cluster.routing.allocation.disk.watermark.low": "88%"
}
}
'
# Disable disk-based allocation temporarily (emergency only!)
curl -X PUT "localhost:9200/_cluster/settings?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.disk.threshold_enabled": false
}
}
'
# Remove read-only blocks from indices
curl -X PUT "localhost:9200/_all/_settings?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"index.blocks.read_only_allow_delete": null
}
'Warning: Adjusting these settings can lead to data corruption if disk space is critically low. Only use as a temporary measure while you address the underlying disk space issue.
For long-term solutions, add storage capacity or rebalance data:
# Add a new data node with more disk space
# Update elasticsearch.yml on new node:
# node.roles: [data]
# Then start the node
# Check shard distribution
curl -X GET "localhost:9200/_cat/shards?v&h=index,shard,prirep,state,node,store&s=store:desc&pretty" -u "username:password"
# Rebalance shards manually
curl -X PUT "localhost:9200/_cluster/settings?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.enable": "all"
}
}
'
# Exclude full nodes from allocation
curl -X PUT "localhost:9200/_cluster/settings?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.exclude._name": "full-node-name"
}
}
'
# Move specific indices to nodes with more space
curl -X POST "localhost:9200/_cluster/reroute?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"commands": [
{
"move": {
"index": "large-index",
"shard": 0,
"from_node": "full-node",
"to_node": "empty-node"
}
}
]
}
'Consider implementing hot-warm architecture with different disk tiers for better capacity management.
Set up monitoring to prevent future occurrences:
# Configure index lifecycle management (ILM)
curl -X PUT "localhost:9200/_ilm/policy/disk-space-policy?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "7d"
},
"set_priority": {
"priority": 100
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}
'
# Set up index templates with ILM
curl -X PUT "localhost:9200/_index_template/logs-template?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "disk-space-policy",
"index.lifecycle.rollover_alias": "logs"
}
}
}
'
# Configure snapshot/restore for backup before deletion
curl -X PUT "localhost:9200/_snapshot/my-backup-repo?pretty" -u "username:password" -H 'Content-Type: application/json' -d'
{
"type": "fs",
"settings": {
"location": "/mnt/elasticsearch-backups"
}
}
'Implement monitoring alerts for:
- Disk usage above 80%
- Index count growth rate
- Shard allocation failures
- Cluster block events
## Advanced Disk Management in Elasticsearch
### Understanding Disk Watermarks
Elasticsearch uses three disk watermarks to protect cluster stability:
1. Low watermark (default: 85%): No new shards allocated to the node
2. High watermark (default: 90%): Shards relocated off the node
3. Flood stage (default: 95%): Index blocks set to read-only-allow-delete
### Disk-Based Shard Allocation
When a node reaches the high watermark, Elasticsearch:
1. Marks shards on that node as "relocating"
2. Attempts to move them to nodes with more free space
3. If no suitable nodes exist, shards remain unassigned
### Index Block Types
Elasticsearch supports several block types:
- read_only: No writes allowed
- read_only_allow_delete: Only deletes allowed (used for flood stage)
- write: No writes allowed (blocks metadata changes)
- metadata: No metadata changes allowed
### Monitoring and Alerting Setup
# Example: Elasticsearch disk alert rule
PUT _watcher/watch/disk_usage_alert
{
"trigger": {
"schedule": { "interval": "5m" }
},
"input": {
"search": {
"request": {
"indices": [".monitoring-es-*"],
"body": {
"query": {
"bool": {
"must": [
{ "range": { "node_stats.fs.total.used_percent": { "gte": 85 } } },
{ "term": { "type": "node_stats" } }
]
}
},
"aggs": {
"nodes": {
"terms": { "field": "node_stats.node.name", "size": 10 },
"aggs": {
"max_usage": { "max": { "field": "node_stats.fs.total.used_percent" } }
}
}
}
}
}
}
},
"condition": {
"compare": { "ctx.payload.aggregations.nodes.buckets.0.max_usage.value": { "gte": 85 } }
},
"actions": {
"send_email": {
"email": {
"to": ["[email protected]"],
"subject": "Elasticsearch Disk Usage Alert",
"body": "Node {{ctx.payload.aggregations.nodes.buckets.0.key}} disk usage is {{ctx.payload.aggregations.nodes.buckets.0.max_usage.value}}%"
}
}
}
}### Capacity Planning Best Practices
1. Monitor growth rates: Track index size increase per day
2. Implement retention policies: Automate deletion of old data
3. Use tiered storage: Hot/warm/cold architecture
4. Regular cleanup: Force merge, clear cache, delete old indices
5. Snapshot before deletion: Always backup before removing data
### Emergency Recovery Procedures
If cluster is completely blocked:
1. Add emergency storage (attach new disk)
2. Temporarily disable disk threshold: cluster.routing.allocation.disk.threshold_enabled: false
3. Remove read-only blocks: index.blocks.read_only_allow_delete: null
4. Rebalance data to new storage
5. Re-enable disk protection
### Cloud-Specific Considerations
- AWS Elasticsearch/OpenSearch: Auto-scaling disk volumes
- Elastic Cloud: Built-in disk monitoring and alerts
- Self-managed: Implement regular disk cleanup scripts
IllegalStateException: There are no ingest nodes in this cluster, unable to forward request to an ingest node
How to fix "There are no ingest nodes in this cluster" in Elasticsearch
ConnectException: Connection refused
How to fix "ConnectException: Connection refused" in Elasticsearch
NodeDisconnectedException: [node] disconnected
How to fix "NodeDisconnectedException: [node] disconnected" in Elasticsearch
SnapshotException: [repository:snapshot] Snapshot could not be read
How to fix "SnapshotException: [repository:snapshot] Snapshot could not be read" in Elasticsearch
AccessDeniedException: action [cluster:admin/settings/update] is unauthorized
AccessDeniedException: action cluster:admin/settings/update is unauthorized