Meili CDC Docs

Troubleshooting and FAQ

Start with the task's status and its Logs tab: errors name the setting to change. This page collects the common ones.

Where to look

  1. The task's state. failed is a configuration problem (fix and start again); retrying is transient and resolves itself; held is a safety guard waiting for you.
  2. The task's Logs tab and the error under its status.
  3. The service log (journalctl -u meilisearch-cdc, docker logs cdc); set CDC_LOG_LEVEL=debug for more.
  4. Test connection in the task wizard, and the connector's last test.

Source errors

Message (excerpt)Cause and fix
postgres: wal_level is "replica" but logical replication needs "logical"Set wal_level = logical and restart PostgreSQL. PostgreSQL.
create replication slot … (the user needs the REPLICATION attribute and a free max_replication_slots entry)Grant REPLICATION; raise max_replication_slots; drop unused cdc_* slots.
replication slot "cdc_…" is active for PID …Another consumer (often a second installation or a duplicate task id) holds the slot. Stop it or use another slot.
has no primary key; add one or run ALTER TABLE … REPLICA IDENTITY FULLAdd a primary key, or set REPLICA IDENTITY FULL and mapping.primaryKey.
mysql: binlog_format is MIXED but change capture needs ROW / binlog_row_image is MINIMAL … / binary logging is disabledFix the server config and persist it. MySQL.
(grant REPLICATION SLAVE, REPLICATION CLIENT ON *.*)Grant the replication privileges to the CDC user.
mongodb: change streams need a replica set or sharded clusterStart mongod --replSet rs0 and run rs.initiate(). MongoDB.
sqlserver: SQL Server Agent is stopped, so the CDC capture job does not runStart the Agent (MSSQL_AGENT_ENABLED=true in containers). SQL Server.
change data capture is not enabled for database … / is not tracked by change data captureRun the printed sp_cdc_enable_db / sp_cdc_enable_table.
dynamodb: table … has no streamEnable a stream with NEW_AND_OLD_IMAGES. DynamoDB.
cockroachdb: changefeeds need rangefeeds …SET CLUSTER SETTING kv.rangefeed.enabled = true as an admin.
kafka: topic "…" does not existUse the exact Debezium topic name.
sqlpoll: source.cursorColumn is requiredChoose a cursor column. SQL polling.

"source position lost … starting a full resync"

Not an error to fix: the stored position no longer exists on the source (a purged binlog, an invalidated or dropped replication slot, an oplog that rolled over, an expired DynamoDB shard, a trimmed Redis stream, SQL Server change rows removed by cleanup, a position older than CockroachDB's GC window). The task copies everything again, with zero-downtime resync if enabled. If it happens often, keep tasks running or extend the source's log retention.

The task is held

A safety guard refused a risky batch; nothing was applied.

  • safety hold: a single batch would delete 5000 of 8000 documents (62% > 20% limit): check whether the source really deleted those rows. If yes, raise maxDeleteRatio (or set it to 0) and Resume, or Resync.
  • safety hold: the source table was truncated; enable safety.allowTruncate or resync the task: decide whether the index should be emptied too.

See safety guards.

Meilisearch errors

Message (excerpt)Cause and fix
index primary key mismatch: index "x" uses "sku" but the task writes "id" …Use another index, change mapping.primaryKeyField, or resync with zero-downtime enabled. Primary key guard.
task "x" already writes index "y" with primary key "z" (409)Two tasks on one index must use the same primary key field.
invalid_api_key, missing_authorization_header, HTTP 401/403Fix the destination's API key and its permissions. API key permissions.
no Meilisearch destination is configured: add one firstAdd a destination, or set MEILI_URL.
Documents in the DLQ with invalid_document_id, invalid_document_geo_field…See Dead letter queue.

409 "single instance mode: MEILI_URL is set …"

With MEILI_URL set, the service writes only to that instance, and creating, deleting or switching destinations is refused. Unset MEILI_URL and restart to manage destinations in the dashboard. See single-instance mode.

Email does not send

Message (excerpt)Fix
the server sent no greeting: it probably expects TLS from the start; use port 465 with TLS, or check the portPort 465 needs TLS mode (or auto).
the server does not speak TLS on this port; use STARTTLS on port 587Use port 587 with STARTTLS (or auto).
the server does not support STARTTLS, so the password would be sent in plain text; use port 465 with TLSUse TLS, or a relay without authentication with mode none.
Links in emails point to http://127.0.0.1:8080Set the public URL in Settings → Email or CDC_PUBLIC_URL.

Dashboard problems

  • "Offline" in the top bar behind a proxy: the proxy buffers Server-Sent Events. See Reverse proxy and TLS.
  • 403 cross-origin request refused on every save: the proxy changes the Host header; forward it unchanged.
  • Signed out after a restart: sessions survive restarts (they are stored); check that the data directory is persistent.
  • 429 too many attempts: wait 15 minutes or restart the service; behind a proxy enable CDC_TRUST_PROXY so one IP does not stand for everyone.
  • Forgot the admin password: meilisearch-cdc admin users reset-password --email … --generate. See recovery recipes.

The service does not start

  • The database is locked: another process (a second instance, or the CLI working offline) has cdc.db open. Run one instance per data directory.
  • cannot decrypt secret / value was encrypted with a key that is not configured: the key changed. Provide the old key as CDC_SECRET_KEY, or as CDC_SECRET_KEY_PREVIOUS to rotate. See key rotation.
  • task …: … then exit: the declarative tasks file has an error. See Declarative tasks file.
  • Permission denied on /data in Docker: a bind mount not writable by uid 65532. See Docker.

FAQ

Does it need Kafka or Debezium?
No. Most sources are read directly. Kafka is one optional source, for databases only Debezium supports.
Can one table feed several Meilisearch instances?
Yes: create one task per destination on the same connector and table. For PostgreSQL each task has its own slot.
Can several tables feed one index?
Yes, with the same primary key field and the upsert write mode, so each task merges its fields. Static fields help tell sources apart.
What delivery guarantee does it give?
At-least-once with idempotent writes: a change may be applied twice after a crash, never lost, and applying it twice gives the same document.
Can I run two replicas for high availability?
No. The state store is single-writer; run one instance and let your orchestrator restart it. Checkpoints make restarts cheap.
Does it change my database?
Only for PostgreSQL (a replication slot and, unless you name one, a publication per task) and CockroachDB (it may enable kv.rangefeed.enabled if allowed). Deleting a PostgreSQL task with drop source objects removes them.
How do I move an installation to another server?
Stop it, copy the data directory (with secret.key, or keep the same CDC_SECRET_KEY), start it there. See Backups.

Meili CDC user guide · last updated 2026-10-26 · Edit this page on GitHub

meilisearch-cdc is open source. Meilisearch is a trademark of Meili SAS; this project is not affiliated with it.