Error 463 permanent on cold sends for instances paired before v0.7.2 — NCT salt never backfilled
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 55/100
Direzione di ricerca
Inizia dal percorso events.Connected e handleAppStateSyncKeyShare, quindi esamina cstoken.go, message.go e il comportamento dell’archivio del salt NCT descritto nell’issue. Confronta la normale chiamata regular_high FetchAppState con il bootstrap forzato suggerito e verifica che un’istanza pre-v0.7.2 con salt vuoto possa recuperare gli invii a freddo senza ripetere il bootstrap indefinitamente.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Instances that were paired before v0.7.2 (when the project dropped the custom whatsmeow-lib fork and switched to official upstream go.mau.fi/whatsmeow) never receive the NCT salt, and therefore can never generate a <cstoken> for first-contact (cold) 1:1 sends. This makes error 463 (NackCallerReachoutTimelocked) permanent for any pre-v0.7.2 instance trying to message a number it has never talked to before — it never self-heals, no matter how many times the instance reconnects.
Root cause
generateCsToken(whatsmeowcstoken.go) requirescli.Store.NCTSalt.GetNCTSalt(ctx)to return a non-empty salt. We confirmed via direct Postgres inspection thatwhatsmeow_nct_saltis completely empty (0 rows) for an instance that has been connected and working for months.- The salt is only delivered through two whatsmeow-internal paths: (1) the one-time History Sync payload sent right after a fresh QR pairing (
message.go,historySync.GetNctSalt()), or (2) an App State Sync patch (regular_highcategory,nct_salt_syncmutation index) fetched viaFetchAppState. - Instances paired before v0.7.2 went through their one-time History Sync using the old custom fork, which had no concept of NCT salt at all — that one-time opportunity is gone forever for those instances.
- Going forward,
regular_highshould self-heal viahandleAppStateSyncKeyShare, but that function callsFetchAppState(ctx, name, false, onlyResyncIfNotSynced=true)— andonlyIfNotSyncedskips categories that already have some stored version, even if that version predates cstoken support and never actually captured the salt mutation. So already-synced-but-stale categories are never re-fetched, and the instance is stuck permanently.
How Baileys solved the identical problem
Baileys hit the exact same gap and fixed it in WhiskeySockets/Baileys#2438 with a dedicated ensureNctSaltSynced() (in chats.ts): on every connection.update → open, if no salt is stored yet, it force-fetches regular_high on its own — independent of the normal "already synced" gating, guarded on the persisted regular_high version so it bootstraps at most once and never loops for accounts that legitimately have no salt yet.
Suggested fix
Port the equivalent of ensureNctSaltSynced() into evolution-go (or ideally into go.mau.fi/whatsmeow itself, so all consumers benefit): on events.Connected, if cli.Store.NCTSalt.GetNCTSalt(ctx) is empty, call cli.FetchAppState(ctx, appstate.WAPatchRegularHigh, true, false) once (forcing fullSync=true, onlyIfNotSynced=false specifically for this bootstrap case), guarded so it only runs once per process/instance to avoid loops for accounts that genuinely have no salt provisioned server-side yet.
Impact
Affects any instance paired before the org's whatsmeow upgrade (in our case, before 2026-07-03 / v0.7.2). For anyone doing bulk migrations of older instances (e.g. from a different provider) into evolution-go, this silently breaks first-contact/cold outreach sends indefinitely, with no error message pointing at the actual cause (surfaces only as server returned error 463 on /send/text, identical to the generic reach-out time-lock).
Environment
- evolution-go v0.7.2 (
go.mau.fi/whatsmeow v0.0.0-20260630180629-b572e5bcb92b) - Instance paired 2026-02-18 (pre-v0.7.2, custom
whatsmeow-libfork era) - Confirmed via direct query:
whatsmeow_nct_salt= 0 rows,whatsmeow_privacy_tokens= 0 rows for the affected contact,whatsmeow_lid_mapcorrectly populated (so LID resolution is not the issue)
- Lingua principale
- Go
- Stelle
- 939
- Fork
- 505
- Merge medio
- 5m
- PR unite (30g)
- 1
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di evolution-foundation/evolution-go
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
evolution-foundation/evolution-go#193 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
evolution-foundation/evolution-go#104 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
evolution-foundation/evolution-go#101 ·
I maintainer di solito rispondono entro 1 giorno
-
POST /group/participant always returns 400 "participants is required and cannot be empty" (wrong validation middleware on route)Forse già presa Una pull request collegata a questa issue è aperta o già unita. Apertabug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
evolution-foundation/evolution-go#97 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 20/100
evolution-foundation/evolution-go#219 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di evolution-foundation/evolution-go
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
scaleway/scaleway-cli#6492 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
taskcluster/taskcluster#9284 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
oasdiff/oasdiff#1337 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
splunk/terraform-provider-splunk#256 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno