[BUG] Webhook config (url/events/headers) wiped on container restart, despite Postgres persistence

Open
#2,694 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
55/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
docker, postgresql, typescript

Research direction

Reproduce the issue through POST /webhook/set/{instance}, GET /webhook/find/{instance}, and a Docker container restart, comparing the webhook configuration before and after. Trace how the webhook URL, events, and headers are stored and restored with DATABASE_PROVIDER=postgresql, including the instance restart path if possible. Done means the configured values remain intact after container and instance restarts, with tests covering the reliable container-restart case.

Written by the indexing model from the issue text.

Description

Welcome!
  • Yes, I have searched for similar issues on GitHub and found none.
What did you do?

We run Evolution API in production with two WhatsApp instances on Baileys, PostgreSQL storage, webhook integration to our own FastAPI receiver (MESSAGES_UPSERT + CONNECTION_UPDATE events, custom x-webhook-secret header for auth).

After restarting the evolution-api container (docker restart), we checked the webhook configuration via GET /webhook/find/{instance} for both instances and found it reset to an empty/default state:

{
  "url": "",
  "events": [],
  "headers": null,
  "enabled": true
}

This happened for both instances simultaneously, immediately after the container restart — not a gradual drift, a clean wipe.

We have a small watchdog script (runs every minute) that checks GET /webhook/find/{instance} against the expected config and re-applies it via POST /webhook/set/{instance} if it drifts. Its log shows this same "url/events/secret wiped" pattern recurring several times over the past week, always shortly after some kind of instance/container restart — most confirmed correlation is with a full docker restart of the container, but we also have some log entries suggesting an /instance/restart/{name} call (not just a full container restart) can trigger the same wipe. We haven't isolated a 100% clean minimal repro for the instance-level-restart case yet — the container-restart case is the one we can reproduce reliably.

What did you expect?

Webhook configuration (url, events, headers) is set once via POST /webhook/set/{instance} and stored in Postgres (DATABASE_ENABLED=true, DATABASE_PROVIDER=postgresql). We expected it to persist across container/instance restarts, since it's meant to be durable configuration, not runtime-only state.

What did you observe instead of what you expected?

Webhook url becomes an empty string, events becomes an empty array, and the custom secret header is dropped — for both instances — right after a container restart. enabled stays true, so the instance silently stops delivering any webhook at all until something notices and re-applies the config. We only caught this because of our own watchdog; without it, inbound message webhooks would just silently stop firing after any restart.

Reproduction steps (container restart case — reliable)
  1. Configure webhook for an instance: POST /webhook/set/{instance} with a url, events (e.g. MESSAGES_UPSERT, CONNECTION_UPDATE), and a custom header.
  2. Confirm it's set: GET /webhook/find/{instance} returns the values you set.
  3. docker restart <evolution-api-container>.
  4. GET /webhook/find/{instance} again — url is "", events is [], headers is null.
Our workaround

A small script runs every minute via cron/systemd timer:

  1. GET /webhook/find/{instance} for each instance.
  2. Compare url, events (as a set, not exact array order), and the secret header against expected values.
  3. If any mismatch, POST /webhook/set/{instance} with the full correct payload again.
  4. Alert (we use Telegram) only when a fix was actually applied, so a real drift doesn't go unnoticed.

This keeps us running, but it's a workaround for state that should be persisted, not something that should need re-checking every minute.

Which version of the API are you using?

evoapicloud/evolution-api:2.4.0-rc2 (reports internally as v2.4.0)

What is your environment?

Linux (CentOS Stream 10), Docker, network_mode: host, PostgreSQL 18 (DATABASE_ENABLED=true, DATABASE_PROVIDER=postgresql), DATABASE_SAVE_DATA_CHATS=false, DATABASE_SAVE_DATA_HISTORIC=false, DATABASE_SAVE_DATA_CONTACTS=false, DATABASE_SAVE_DATA_LABELS=false.

If applicable, paste the log output
GET /webhook/find/instance-a  (right after docker restart)
{
  "id": "...",
  "url": "",
  "headers": null,
  "enabled": true,
  "events": [],
  "webhookByEvents": false,
  "webhookBase64": false,
  "instanceId": "..."
}
Dominant language
TypeScript
Stars
9.6k
Forks
7.3k
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from evolution-foundation/evolution-api

All issues in evolution-foundation/evolution-api

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.