How to fix ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)] in Elasticsearch

ElasticsearchINTERMEDIATEHIGHUpdated Dec 22, 2025· 141 views

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.

Quick fix

Fixes ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]

# 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"
  1. Check cluster disk usage and health status
  2. Free up disk space on affected nodes
  3. Adjust disk watermark thresholds temporarily
  4. Add more disk capacity or rebalance shards
elasticsearch — error
# 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"
ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]

What this error means

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.

Typical symptoms

  • Indexing operations fail with "ClusterBlockException" errors
  • Bulk API requests show "FORBIDDEN/12/index read-only" failures
  • Cluster health shows indices in "read-only" state
  • Disk usage monitoring shows high utilization on data nodes
  • Write operations fail but delete operations succeed
  • Application logs show repeated block exceptions during indexing

Common causes

  1. Disk space on data nodes has exceeded flood stage threshold (95% by default)
  2. Cluster disk allocation settings are too restrictive
  3. Index-level read-only blocks were manually applied
  4. Cluster is in a recovery state after node failures
  5. Shard allocation is disabled due to disk space constraints
  6. Index metadata corruption triggering protective blocks
  7. Cluster settings have low disk watermark thresholds configured

How to fix "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)]"

1Check cluster disk usage and health status

First, examine the current disk usage and cluster health to understand the scope of the problem:

bash
# 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

2Free up disk space on affected nodes

If disk space is the issue, free up space by deleting old indices or documents:

bash
# 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.

3Adjust disk watermark thresholds temporarily

If you cannot immediately free enough disk space, you can adjust the disk watermark thresholds:

bash
# 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.

4Add more disk capacity or rebalance shards

For long-term solutions, add storage capacity or rebalance data:

bash
# 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.

5Implement monitoring and prevention strategies

Set up monitoring to prevent future occurrences:

bash
# 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 notes

## 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

yaml
# 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": ["admin@example.com"],
        "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

Frequently asked questions

What does "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / all" mean?
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.
How do I fix "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / all"?
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.
What causes "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / all"?
Disk space on data nodes has exceeded flood stage threshold (95% by default) Cluster disk allocation settings are too restrictive Index-level read-only blocks were manually applied
Is the "ClusterBlockException: blocked by: [FORBIDDEN/12/index read-only / all" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading