Zammad Elasticsearch Errors: Fix Guide
The Problem
Zammad’s search isn’t returning results, or the application throws Elasticsearch-related errors. Common symptoms include:
Elasticsearch is not reachable, probably because it's not running or even installed.
Elasticsearch cluster health is "red"
Or in the Zammad rails console or logs:
Faraday::ConnectionFailed: Connection refused - connect(2) for "zammad-elasticsearch" port 9200
Search may return no results even though tickets exist, or indexing may lag behind — new tickets don’t appear in search for hours or never.
The Cause
Zammad relies on Elasticsearch for full-text search across tickets, articles, customers, and attachments. When Elasticsearch is unhealthy, search degrades or breaks entirely.
| Cause | Symptom | Frequency |
|---|---|---|
vm.max_map_count too low | Elasticsearch crashes on startup | Very common (Docker) |
| Insufficient heap memory | OOM kills, cluster red | Common |
| Index corruption | Partial search results, missing tickets | Occasional |
| Network issue between containers | ”Connection refused” | Common (Docker network changes) |
| Elasticsearch version mismatch | Startup failures, deprecation errors | After upgrades |
| Disk space full | Read-only index, write rejections | Gradual onset |
The Fix
Method 1: Set vm.max_map_count (Most Common in Docker)
Elasticsearch requires vm.max_map_count to be at least 262144. Most Linux distributions default to 65530, which causes Elasticsearch to crash silently.
Check the current value:
sysctl vm.max_map_count
Set it temporarily (until reboot):
sudo sysctl -w vm.max_map_count=262144
Set it permanently:
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Then restart the Elasticsearch container:
docker compose restart zammad-elasticsearch
Method 2: Increase Elasticsearch Heap Size
Elasticsearch defaults to 1 GB heap, which is insufficient for Zammad installations with thousands of tickets. Zammad’s official recommendation is 2 GB minimum.
In your docker-compose.yml, set the heap via the ES_JAVA_OPTS environment variable:
services:
zammad-elasticsearch:
image: bitnami/elasticsearch:8.17.3
restart: unless-stopped
environment:
ES_JAVA_OPTS: "-Xms2g -Xmx2g" # 2 GB heap (min = max)
volumes:
- elasticsearch-data:/bitnami/elasticsearch/data
ulimits:
memlock:
soft: -1
hard: -1
The -Xms and -Xmx values should always match (prevents heap resizing overhead). Set them to no more than 50% of available RAM, with the remainder reserved for the OS file cache.
| Available RAM | Recommended ES Heap | Notes |
|---|---|---|
| 4 GB | 1 GB | Minimum, small installations only |
| 8 GB | 2 GB | Recommended for most setups |
| 16 GB | 4 GB | Large installations (50K+ tickets) |
| 32 GB+ | 8 GB max | ES doesn’t benefit from heaps >8 GB |
Method 3: Rebuild the Elasticsearch Index
If search returns incomplete results or tickets are missing, rebuild the index:
# Enter the Zammad rails container
docker compose exec zammad-railsserver rails r "SearchIndexBackend.create_index"
# Reindex all data
docker compose exec zammad-railsserver rails r "SearchIndexBackend.rebuild_index"
For Zammad Docker Compose setups using the zammad-init container, you can also trigger reindexing via rake:
docker compose exec zammad-railsserver bundle exec rake zammad:searchindex:rebuild
This process can take minutes to hours depending on ticket volume. Search will be degraded during reindexing.
Method 4: Fix Container Networking
If Zammad can’t reach Elasticsearch at all (“Connection refused”):
Check that both containers are on the same Docker network:
docker network inspect $(docker compose ps -q zammad-railsserver | head -1 | xargs docker inspect -f '{{range .NetworkSettings.Networks}}{{.NetworkID}}{{end}}')
Verify Elasticsearch is actually running:
docker compose ps zammad-elasticsearch
If it shows “restarting” or “exited,” check the logs:
docker compose logs zammad-elasticsearch --tail 50
Test connectivity from the Zammad container:
docker compose exec zammad-railsserver curl -s http://zammad-elasticsearch:9200/_cluster/health?pretty
Expected response includes "status" : "green" or "status" : "yellow". Red means the cluster needs attention.
Method 5: Handle Disk Space Issues
When disk usage exceeds 95%, Elasticsearch switches indices to read-only mode. New tickets stop being indexed.
Check disk usage:
docker compose exec zammad-elasticsearch curl -s http://localhost:9200/_cat/allocation?v
If indices are read-only, clear the read-only block after freeing space:
docker compose exec zammad-elasticsearch curl -X PUT "localhost:9200/_all/_settings" \
-H 'Content-Type: application/json' \
-d '{"index.blocks.read_only_allow_delete": null}'
Free space by pruning old data:
# Remove unused Docker images and volumes
docker system prune -a --volumes
Or increase the Elasticsearch data volume size if using named volumes.
Prevention
| Practice | Why |
|---|---|
Set vm.max_map_count=262144 in /etc/sysctl.conf | Survives reboots, prevents the #1 Elasticsearch failure |
| Allocate at least 2 GB ES heap | Prevents OOM kills as ticket volume grows |
| Monitor disk usage on ES data volume | Catches full-disk before indices go read-only |
Run SearchIndexBackend.rebuild_index after major upgrades | Ensures index schema matches new Zammad version |
| Keep Elasticsearch version aligned with Zammad requirements | Prevents compatibility issues |
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments