Visitar URL original
Instance stays "open" but stops receiving messages after "stream errored out" (ack class="status") — Baileys #2858, fix with 3 lines · Issue #2778 · evolution-foundation/evolution-api · GitHub
Skip to content

Instance stays "open" but stops receiving messages after "stream errored out" (ack class="status") — Baileys #2858, fix with 3 lines #2778

Open

Description

@innovateai2025

Welcome!

  • Yes, I have searched for similar issues on GitHub and found none.

What did you do?

Running evoapicloud/evolution-api:v2.3.7 (Baileys 7.0.0-rc.9), Postgres + Redis, ~30 QR instances with Chatwoot integration. Nothing special: instances were just running normally.

What did you expect?

Instances that show connectionStatus "open" keep receiving incoming messages: they are stored in the Message table and the messages.upsert webhook is fired.

What did you observe instead of what you expected?

Some instances stay "open" but stop receiving: messages arrive on the phone, but nothing is stored in the Message table and no webhook fires. Other instances on the same server keep working.

  • Restarting the instance (/instance/restart) does NOT fix it.
  • Restarting the whole container does NOT fix it.
  • Logout + new QR fixes it, until it happens again (in one case, less than 3 hours later).

Each episode starts with a Baileys "stream errored out" whose node is an ack with class="status" (see logs below). Within 1-3 seconds, the affected instance auto-reconnects (its Instance.updatedAt changes) and from then on it receives nothing.

Note: this is not the same as #2773 (disappearing messages). Here ALL incoming messages stop for the instance, regardless of the contact.

Screenshots/Videos

No response

Which version of the API are you using?

2.3.7

What is your environment?

Docker

Other environment specifications

Docker image evoapicloud/evolution-api:v2.3.7 (Baileys 7.0.0-rc.9), PostgreSQL 17, Redis 7 (CACHE_REDIS_ENABLED=true), Chatwoot integration enabled, ~30 WHATSAPP-BAILEYS (QR) instances on the same server.

If applicable, paste the log output

{"level":50,"msg":"stream errored out",
 "reasonNode":{"tag":"ack","attrs":{"class":"status","type":"text","id":"AC9087..."}},
 "fullErrorNode":{"tag":"stream:error","attrs":{},
   "content":[{"tag":"ack","attrs":{"class":"status","type":"text","id":"AC9087..."}}]}}

type can be text or media. We saw 3-9 of these per hour on our server, each one followed by an instance auto-reconnecting.

Additional Notes

Root cause: Baileys issue #2858 (WhiskeySockets/Baileys#2858). Since late September 2026 WhatsApp sends top-level <status> stanzas (Status updates) that Baileys never acks. ~50 min later the server closes the stream with the missing ack; on reconnect the same <status> is redelivered and never acked, so the session stays "open" without receiving. The upstream fix (PR #2866) is not released yet.

Fix: in node_modules/baileys/lib/Socket/messages-recv.js, right after the CB:notification handler (around line 1220 in rc.9), add:

ws.on('CB:status', (node) => {
    sendMessageAck(node).catch(error => onUnexpectedError(error, 'acking status stanza'));
});

A plain ack, no error code (a NACK keeps the stanza pending). Evolution ignores Status (readStatus: false), so nothing is lost.

To make it persistent, we build a derived image instead of editing the container:

FROM evoapicloud/evolution-api:v2.3.7
COPY patch-status.cjs /tmp/
RUN node /tmp/patch-status.cjs /evolution/node_modules/baileys \
 && node --check /evolution/node_modules/baileys/lib/Socket/messages-recv.js

Our script inserts those lines and fails the build if the Baileys version is not exactly 7.0.0-rc.9 or the anchor code is not found, so it can't silently break on upgrade. Happy to share it.

Result: deployed on two servers. Zero "stream errored out" with class "status" since then, and an instance that had been broken for 14+ hours started receiving again after the restart, without re-pairing.

Suggestion: bump Baileys once #2866 is released, or ship this handler via patch-package in the meantime.

Activity

  1. Wellers0n commented on Nov 5, 2026

    @Wellers0n

    I’m also experiencing this bug.

  2. guilherme-skillsoft commented on Nov 5, 2026

    @guilherme-skillsoft

    Kudos for the fix!

    Using on 2 different instances and no problems since patching it.

  3. jcalencar commented on Nov 5, 2026

    @jcalencar

    same bug here

  4. MarToxAk commented on Nov 7, 2026

    @MarToxAk

    Opened #2785 with a fix: it backports WhiskeySockets/Baileys#2883 (ack top-level <status> stanzas) through patch-package on develop (Baileys 7.0.0-rc13).

    The same change on the compiled rc.9 inside 2.4.0-rc2 fixed it here: 951 <status> stanzas acked in the first 3 minutes, and the held-back inbound messages were released in about 1 minute. No new QR was needed.

  5. jailtonseguros commented on Nov 7, 2026

    @jailtonseguros

    Estou com esse problema também, vou testa e ver como fica, o de vocês normalizou com esse versão MarToxAk?

  6. julianomatias commented on Nov 9, 2026

    @julianomatias

    Implementamos e está funcionando. Parabéns

  7. rafaelcosta-BR commented on Nov 9, 2026

    @rafaelcosta-BR

    Same issue here, and the community patch fixed it. Sharing our data in case it helps others.

    Environment: evoapicloud/evolution-api:v2.3.7 (Baileys 7.0.0-rc.9), Postgres 16, Redis 7, Chatwoot integration, Docker.

    Symptoms (6-7 Nov 2026):

    • One instance stopped receiving messages. connectionState kept returning open, but nothing was saved to Message and nothing reached Chatwoot.
    • The log showed stream errored out with reasonNode: {tag: 'ack', attrs: {class: 'status', type: 'media'}} exactly every 3000 s: 20 times in about 16 h.
    • Restarting the container did not help. Logging out and scanning a new QR brought messages back for a few hours only.
    • On a second server (Swarm, same image, 2 instances), both instances had the same class=status drops. One of them stopped receiving for about 5 hours.

    Fix: we applied the ack handler routed through processNode (the approach from WhiskeySockets/Baileys#2883, with the try/catch so an error does not leave the offline queue stuck). It runs as a derived image whose build fails if Baileys is not exactly 7.0.0-rc.9:

    const handleStatus = async (node) => {
        try { await sendMessageAck(node); }
        catch (error) { onUnexpectedError(error, 'acking status stanza'); }
    };
    // in makeOfflineNodeProcessor's map: ['status', handleStatus]
    ws.on('CB:status', async (node) => {
        await processNode('status', node, 'acking status stanza', handleStatus);
    });

    Result:

    • Server 1: 0 stream errors in 47 h after the patch (before: 20 in 16 h). Messages are flowing normally, and no new QR was needed when the patched container replaced the old one.
    • Server 2: patched this morning; both instances reconnected in about 1 minute with their saved sessions (no QR), passed the 50-minute mark with 0 stream errors, and the instance that had gone deaf is receiving again.

    Thanks to @innovateai2025 and everyone in WhiskeySockets/Baileys#2858 for the analysis. Hoping #2785 or an official Baileys release lands soon.

  8. carlosasjr commented on Nov 10, 2026

    @carlosasjr

    Same issue on evoapicloud/evolution-api:v2.3.7 (Baileys 7.0.0-rc.9), confirming the root cause and that #2785's approach works in production.

    Symptoms (9–10 Nov 2026): one instance stopped receiving for ~17h while connectionState stayed open and sending still worked. The instance's message count stayed frozen. A container restart reconnected it (CONNECTED TO WHATSAPP) but nothing was delivered in the following minutes, so restarting does not cure it.

    Fix: derived image from v2.3.7 with the #2883 backport (handleStatus + CB:status + status in the offline map). Within 1 minute of the swap the instance started receiving again and the held backlog (~17h) was fully delivered in ~6 minutes, with no re-pairing (no new QR) and no duplicates on our side.

    Note for anyone patching 2.3.7 (rc.9) rather than develop: rc.9's offline queue loop has no per-node try/catch, so one throwing node (seen here with a w:gp2 notification) stops the backlog recovery. rc13 already wraps it (offline-node-processor.ts), so this only matters for 2.3.x backports.

    Could #2785 get a review from the maintainers? It's currently blocked and many users here are running it as a community patch. A 2.3.8 with this fix would help everyone on the stable line.

  9. ctrindade0503 commented on Nov 13, 2026

    @ctrindade0503

    Confirming this on another production setup, plus a way to apply the patch without building a derived image (useful if you deploy with Compose/Coolify and just want to keep the official image).

    Environment: evoapicloud/evolution-api v2.3.7 (Baileys 7.0.0-rc.9), Docker Compose, 1 business number with a few thousand contacts, several other instances on the same container. Symptoms exactly as described here: instance open, sending works, nothing received; restarting the instance/container did not help; a new QR only helped for 1.5–2.5 h.

    Before the patch (logs): stream errored out with reasonNode: ack class="status" type="media", repeated; about 10 class":"status" hits per 3 h and a reconnect every ~50 min.

    Patch (same 3 lines as in the issue, inserted before CB:notification):

    ws.on('CB:status', (node) => {
        sendMessageAck(node).catch(error => onUnexpectedError(error, 'acking status stanza'));
    });

    How I applied it without a custom image: override the entrypoint and mount a small idempotent script (in Coolify it can be created with the content: key of a bind volume; plain Compose can just bind a file):

    services:
      api:
        image: evoapicloud/evolution-api@sha256:<the digest you are running>   # pin it, see note below
        entrypoint:
          - /bin/bash
          - -c
          - '. ./Docker/scripts/deploy_database.sh && (node /patch/patch-status.cjs || true) && npm run start:prod'
        volumes:
          - ./patch-status.cjs:/patch/patch-status.cjs:ro

    patch-status.cjs:

    const fs = require('fs');
    const { spawnSync } = require('child_process');
    const dir = '/evolution/node_modules/baileys';
    const file = dir + '/lib/Socket/messages-recv.js';
    const log = (m) => console.log('[patch-status] ' + m);
    try {
      const ver = JSON.parse(fs.readFileSync(dir + '/package.json', 'utf8')).version;
      if (ver !== '7.0.0-rc.9') { log('Baileys ' + ver + ' != 7.0.0-rc.9: nothing done'); process.exit(0); }
      const s = fs.readFileSync(file, 'utf8');
      if (s.includes("ws.on('CB:status'")) { log('already applied'); process.exit(0); }
      const anchor = "    ws.on('CB:notification'";
      const i = s.indexOf(anchor);
      if (i < 0 || !s.includes('sendMessageAck') || !s.includes('onUnexpectedError')) { log('anchor not found: nothing done'); process.exit(0); }
      const add = "    ws.on('CB:status', (node) => {\n        sendMessageAck(node).catch(error => onUnexpectedError(error, 'acking status stanza'));\n    });\n";
      fs.copyFileSync(file, file + '.orig');
      fs.writeFileSync(file, s.slice(0, i) + add + s.slice(i));
      const r = spawnSync(process.execPath, ['--check', file]);
      if (r.status !== 0) { fs.copyFileSync(file + '.orig', file); log('invalid syntax: original restored'); process.exit(0); }
      log('APPLIED: CB:status is now acked');
    } catch (e) { log('error: ' + (e && e.message)); }
    process.exit(0);

    It only acts on exactly 7.0.0-rc.9, is a no-op if already applied, validates with node --check, restores the backup on failure and never blocks the container from starting (|| true). I also tested it in a throwaway container from the same image before touching production.

    Result (11.5 h after the restart):

    • class":"status" errors: 0 (vs ~10 per 3 h before).
    • Reconnects: 2 in 11.5 h (vs one every ~50 min), and the session kept receiving after both. 38 inbound messages received in that window.
    • Right after the restart, ~20 messages that WhatsApp had been holding for ~4 h were delivered at once (same behaviour already reported above). Worth knowing if you have an automation that replies to inbound messages: it will fire on that backlog.

    Things I noticed that may help others:

    1. Pin the image. My :latest had moved: the digest I was running, the current latest digest and the v2.3.7 tag digest were three different images. The patch is tied to Baileys rc.9, so pinning by digest (or re-checking the script after any pull) avoids a silent change.
    2. A different, much rarer variant remains: I still see occasional stream errored out for ack class="notification" with type="encrypt" (x2) and type="w:gp2" (x1) in ~10 h across all instances on the server. Each caused a ~1 s reconnect and did not leave the session deaf, but it looks like the same family (a top-level stanza that never gets acked). Probably worth handling in the upstream fix as well.
    3. Not related to the patch, but if you delete and recreate an instance, the new one has no webhook configured; nothing reaches your app even though Evolution is receiving. Re-apply the webhook.

    Sources I relied on: the analysis in this issue and WhiskeySockets/Baileys#2858. Everything above is one user's data, not an official verification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions