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.

CauseSymptomFrequency
vm.max_map_count too lowElasticsearch crashes on startupVery common (Docker)
Insufficient heap memoryOOM kills, cluster redCommon
Index corruptionPartial search results, missing ticketsOccasional
Network issue between containers”Connection refused”Common (Docker network changes)
Elasticsearch version mismatchStartup failures, deprecation errorsAfter upgrades
Disk space fullRead-only index, write rejectionsGradual 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 RAMRecommended ES HeapNotes
4 GB1 GBMinimum, small installations only
8 GB2 GBRecommended for most setups
16 GB4 GBLarge installations (50K+ tickets)
32 GB+8 GB maxES 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

PracticeWhy
Set vm.max_map_count=262144 in /etc/sysctl.confSurvives reboots, prevents the #1 Elasticsearch failure
Allocate at least 2 GB ES heapPrevents OOM kills as ticket volume grows
Monitor disk usage on ES data volumeCatches full-disk before indices go read-only
Run SearchIndexBackend.rebuild_index after major upgradesEnsures index schema matches new Zammad version
Keep Elasticsearch version aligned with Zammad requirementsPrevents compatibility issues

Comments