Genuka WA docs

WhatsApp error 131026: Message undeliverable — fix

WhatsApp error 131026 (Message Undeliverable): number not on WhatsApp, terms not accepted or app too old. How to diagnose it and what to do next.

WhatsApp error 131026 means Meta could not deliver the message to the recipient: the number is not on WhatsApp, the person has not accepted the latest terms of service, or their app is too old. Do not retry on WhatsApp. Check the number you stored, then reach the person through another channel such as SMS or email.

What does error 131026 mean?

Meta describes it this way (Cloud API error codes):

"Unable to deliver message. Reasons can include: The recipient phone number is not a WhatsApp phone number. Recipient has not accepted the new Terms of Service and Privacy Policy. Recipient using an old WhatsApp version."

Three possible causes, all on the recipient's side. For the third one, Meta lists the minimum app versions:

AppMinimum version
Android2.21.15.15
SMBA (WhatsApp Business, Android)2.21.15.15
iOS2.21.170.4
SMBI (WhatsApp Business, iOS)2.21.170.4
KaiOS2.2130.10
Web2.2132.6

The title that comes with the code in the message field is "Message Undeliverable" (360dialog's list). It names the symptom, not the cause: the code and error_data.details are what tell you why.

When does error 131026 happen?

  • The number has no WhatsApp account: a landline, a switchboard number, a typo in a form.
  • The number is badly formatted: without + and a country code, a local number can be read as belonging to another country and land on someone without WhatsApp. Always write to in international format, for example +237690000001.
  • The recipient's app is out of date, or they have not accepted the new terms of service.

Where do you see it in Genuka WA?

The most common case: Meta accepts the send, then reports the failure on the status webhook.

ChannelWhat you get
message_status webhookdata.status: "failed", data.errors[0].code: 131026
POST /api/v1/messages response, when Meta refuses on the call400, "error": "send_recipient_permanent", meta.code: 131026
CampaignThe recipient turns failed, with Meta's message in errorMessage; it is never retried
Dashboard, Inbox sectionThe failed bubble; "See why" shows Meta's code and details
message_status webhook received by your endpoint (excerpt)
{
  "id": "dlv_2f8c1a...",
  "type": "message_status",
  "field": "messages",
  "connection_id": "cn77...",
  "data": {
    "id": "wamid.HBgLMjM3...",
    "status": "failed",
    "timestamp": "1791451867",
    "recipient_id": "237690000001",
    "errors": [
      {
        "code": 131026,
        "title": "…",
        "message": "…",
        "error_data": { "details": "…" },
        "href": "/documentation/business-messaging/whatsapp/support/error-codes"
      }
    ]
  }
}

data is Meta's status object, passed through untouched: error_data.details varies with the case and may name the cause.

How do I fix error 131026?

Do not retry on WhatsApp. The same send will fail the same way. Genuka WA classifies 131026 as recipient_permanent and never retries it, in a campaign or a single send.

Check the number as you stored it: country code, extra or missing digits, a number typed into a "landline" field.

Reach the person through another channel, SMS or email, as Meta recommends, and ask them to check three things: that they can message your WhatsApp Business number themselves, that they have accepted the latest terms (Meta points to Settings > Help and Settings > Application information, which show the prompt when needed), and that their app is up to date.

Mark the contact as unreachable on WhatsApp in your database, and only re-enable it when they write to you: an inbound message proves they can receive.

// app/api/webhooks/whatsapp/route.ts
import { verifySignature } from "@genuka/whatsapp/webhooks";

export async function POST(request: Request) {
  const raw = await request.text();
  const signature = request.headers.get("x-genuka-signature");
  if (!(await verifySignature(process.env.WEBHOOK_SECRET!, raw, signature))) {
    return new Response("invalid signature", { status: 401 });
  }

  const event = JSON.parse(raw);
  if (event.type === "message_status" && event.data.status === "failed") {
    const codes: number[] = (event.data.errors ?? []).map((e: { code: number }) => e.code);
    if (codes.includes(131026)) {
      // Yours to write: the contact moves to SMS/email until their next inbound message.
      void markWhatsAppUnreachable(event.data.recipient_id);
    }
  }
  return new Response("ok");
}

How do I prevent error 131026?

  • Validate numbers at input, in international format with a country code.
  • Get the contact to reach you on WhatsApp first when you can, with a "Message us on WhatsApp" link: a number that has already written to you is a number that receives.
  • Listen to the message_status webhook rather than the send response: a 200 means "accepted by Meta", not "delivered".
  • Keep a fallback channel for critical messages such as login codes. The WhatsApp OTP in Node.js guide plans for it.
  • 131050: the recipient does receive WhatsApp, but stopped your marketing messages.
  • 131049: a marketing message held back by Meta for this recipient, to try again later.
  • 131047: the 24-hour window is closed; a template will go through.

FAQ

Should I retry a send that failed with 131026?

Not on WhatsApp. Until the recipient's situation changes (WhatsApp installed, app updated, terms accepted), the same send will fail.

Why was the send response 200 when the message failed?

Because Meta accepted the request before attempting delivery. Meta states that its errors come back in the response, by webhook, or both, and recommends watching both. A 131026 most often arrives on the status webhook.

How do I find the 131026 recipients of a campaign?

GET /api/v1/campaigns/{id}/recipients?status=failed&limit=1000 lists failed recipients with Meta's message, 200 by default and 1,000 at most, with no pagination. The numeric code arrives on the message_status webhook: store it there if you want to filter by cause, and it is the only complete list for a large campaign.

Is a message that failed with 131026 billed?

Not by Meta, which only charges for a template message when it is delivered (Meta, Pricing). On the Genuka WA side, however, a send Meta accepted counts against your subscription quota even if delivery fails afterwards: drop unreachable numbers from your next sends.

Sources

On this page