Troubleshooting: WeChat and Zalo CHANNEL_NOT_CONFIGURED and credential precedence
WeChat and Zalo are bring-your-own-credential beta channels. A send on either fails closed —503 CHANNEL_NOT_CONFIGURED — when neither your
organization’s credential row nor the operator’s platform default is set; and
it fails silently as the wrong account when both are set and precedence was
not what you expected. This page covers the resolution order, the expiry
drift on WeChat’s ~2-hour token, and the inbound-reply gap that shows up
after a credential rotation.
The content-side gates (VALIDATION_ERROR on templates) are covered by
Troubleshooting: KakaoTalk Alimtalk and Friendtalk gates,
and the inbound-routing matrix is covered by
Troubleshooting: APAC inbound no-route.
Resolution order — per-organization wins
Both channels resolve credentials the same way, mirrored on the WeChat channel page and Zalo channel page:- Per-organization credentials connected under Settings → Channels → WeChat (or Zalo) — stored encrypted at rest.
- Platform default — a cluster-wide credential the operator sets with an
environment variable (
DEVOTEL_WECHAT_ACCESS_TOKENorDEVOTEL_ZALO_ACCESS_TOKEN), consulted only when the organization has none.
503 CHANNEL_NOT_CONFIGURED. If both are set, every send goes as
the per-organization brand — the platform default is invisible to that
organization until the row is removed.
Symptom map
Why CHANNEL_NOT_CONFIGURED is fail-closed by design
The point of the check is to stop a missing credential from sending
anyway on the platform default, which would put a customer’s brand under an
unexpected Official Account. The same check that produces the 503 is the
thing that prevents wrong-brand sends. When you see it, treat it as
“the channel is safely refusing the send,” not as a broken integration.
Worked example — a WeChat send that succeeded on the wrong account
Support says: “our WeChat sends land on a random OA we do not recognize.” The check sequence:- Open Settings → Channels → WeChat. Note whether a row exists.
- If a row does exist, its OA is the one sending — that is precedence, not leakage. Replace the token with the one you intend.
- If no row exists, the platform default is the sender — either accept that and proceed, or ask your operator which cluster default is set.
Worked example — a WeChat token that expires on a leash
WeChat’scgi-bin/token grant returns a token good for about two hours. A
rotation sidecar that re-pastes every 1h50m from your own refresh loop keeps
the channel working; a manual paste schedule keeps it broken half the time.
TEMPLATESENDJOBFINISH callbacks, reply normalization) is at
WeChat channel page — Receive inbound replies.
What not to try
- Do not set the platform default to mask a missing per-org row. A wrong-brand send to your customers is far worse than the 503 the channel was trying to save you from. Connect the per-organization row instead.
- Do not retry a 503. Validation and configuration errors are deterministic — the same request fails every time.
- Do not rotate a WeChat token by hand under a cadence you will not sustain at ~2-hour intervals. Either run a refresh job or, on higher tiers, use WeChat’s stable-token grant type if you are provisioned for it.
- Do not edit the credential row by hand inside tenant data — the
dashboard writes it under
settings.channels.wechat/settings.channels.zaloencrypted at rest; direct tenant edits break the decrypt envelope. Connect/disconnect through the dashboard surface.
When to escalate
Open a support ticket when the connected row exists (verified in the dashboard) and sends still return 503, or when the resolution chain itself precedes a value that contradicts what the dashboard shows. Include:- Your tenant id (dashboard under Settings → Organization, or
organizationIdonGET /api/v1/me). - Whether a platform default was set on your cluster and when.
- One request ID of a failing send.
- The channel — wechat or zalo — plus whether you are using the direct endpoint or the campaign route.
See also
- WeChat channel page — the channel’s full error table, token grant details, and inbound-reply wiring
- Zalo channel page — the ZNS credential and template flow
- KakaoTalk template gates — the
VALIDATION_ERRORlayer that sits above credentials - APAC inbound no-route — the inbound-reply matrix when replies stop after rotation