All Blog

Why Is My Message Not Delivering? 2026 Fix Guide Today

10 min read
Jun 10, 2026

Why Is My Message Not Delivering.png

TL;DR: The Fastest Way to Diagnose Message Delivery

If you are asking “why is my message not delivering,” the answer usually falls into one of five buckets: device/network problems, recipient availability, carrier or platform filtering, app-level permissions, or backend/SDK integration errors.

Here is the quick version:

  • For personal messaging apps: Check internet connectivity, recipient blocking, app permissions, phone number format, iMessage/RCS fallback settings, and whether the platform is experiencing outages.
  • For SMS/RCS: Delivery can fail because of carrier filtering, invalid numbers, roaming issues, spam rules, unsupported RCS status, or missing fallback to SMS/MMS.
  • For WhatsApp, Messenger, Telegram, or in-app chat: Delivery depends on account state, recipient privacy settings, network access, push notification settings, and whether the app’s servers accepted the message.
  • For developers: Separate “message sent from client,” “message accepted by server,” “message stored,” “message pushed,” and “message read.” These are different delivery states.
  • For production chat apps: Use a real-time messaging platform such as Tencent RTC Chat, monitor delivery callbacks, persist messages, add retries, and test push notification paths.

This guide walks through a practical troubleshooting process for consumers, support teams, and developers building real-time chat. If you are implementing chat yourself, the Tencent RTC Chat SDK documentation and Free Chat API are useful starting points.

Free Chat API — free forever: 1,000 MAU, no concurrency limits, push notifications included.

What “Message Not Delivering” Actually Means

Before fixing the problem, define what “not delivering” means. Many messaging products show similar-looking errors, but the underlying causes are different.

A message can fail at several stages:

StageWhat happenedCommon user-facing symptomTypical owner
ComposeThe user typed the messageSend button disabledApp or device
Local sendThe app tried to sendSpinning icon, clock iconApp/network
Server acceptBackend accepted the messageOne check mark, “sent”Messaging provider
Store/routeServer stored and routed itStill not visible to recipientBackend/provider
Push/notifyRecipient was notifiedDelivered but no alertPush provider/device
Recipient syncRecipient app fetched itDelivered lateRecipient network/app
Read receiptRecipient opened itDelivered but unreadUser behavior/privacy

This distinction matters because “sent,” “delivered,” and “read” are not interchangeable:

  • Sent means the sender’s app or backend accepted the message for processing.
  • Delivered means the recipient’s device, app session, or mailbox received it, depending on platform semantics.
  • Read means the recipient opened or acknowledged it, if read receipts are enabled.
  • Failed means the platform stopped trying, or the client could not hand the message to the service.
  • Pending means the platform may retry automatically.

For example, Apple explains that iMessage and SMS/MMS use different delivery mechanisms, and Apple’s support guidance asks users to check network, activation, and SMS/MMS availability when messages fail (Apple Support). Google’s RCS documentation also distinguishes modern RCS chats from SMS/MMS fallback behavior in Google Messages (Google Messages Help). For business and app messaging, the exact meaning depends on your messaging API and callback model.

For developers building with Tencent RTC, the practical approach is to instrument every stage. Tencent RTC provides real-time messaging capabilities through Chat SDKs, and you can combine messaging with Call SDK, Live, or Conference when your product needs voice, video, live streaming, or meetings.

The 12 Most Common Reasons Messages Do Not Deliver

When someone asks “why is my message not delivering,” these are the most common root causes. Work through them in order, because the simplest causes often look like platform failures.

1. The Sender Has No Stable Network Connection

If your phone or browser cannot reach the messaging service, the message stays pending or fails immediately.

Check:

  • Wi-Fi is connected and has internet access.
  • Mobile data is enabled for the app.
  • Airplane mode is off.
  • VPN, proxy, firewall, or private DNS is not blocking the service.
  • The app is allowed to use background data.
  • Browser apps have permission to access network resources.

For web chat, test the same account in another browser. If it works there, the issue may be browser cache, service worker state, local storage, blocked cookies, or an extension.

2. The Recipient Is Offline or Has Disabled Sync

Some messaging systems only mark messages as delivered when the recipient’s device receives them. If the recipient is offline, has uninstalled the app, disabled data, or has no push notification token, the message may remain sent but not delivered.

In modern chat architecture, offline delivery usually depends on:

  • Message persistence on the server
  • Device token registration
  • Push notification delivery through APNs, FCM, or vendor push services
  • Recipient app sync when reopened

Apple Push Notification service and Firebase Cloud Messaging each have their own delivery constraints and token lifecycle rules. Google’s FCM documentation, for instance, explains message priority, TTL, and delivery behavior for Android and web push (Firebase Cloud Messaging).

3. You Were Blocked or the Recipient Changed Privacy Settings

If one person’s messages never deliver to a specific recipient but other conversations work, blocking or privacy settings may be involved.

Signs include:

  • Calls do not connect.
  • Messages remain on one check mark.
  • Profile photo or status disappears.
  • Group messages work differently from 1:1 messages.
  • Other recipients receive your messages normally.

Be careful: no single sign proves you were blocked. Platforms intentionally avoid exposing definitive block status to protect user privacy.

4. The Phone Number, User ID, or Address Is Invalid

For SMS and RCS, invalid phone number formatting is a frequent cause. International messaging should use E.164 formatting, such as +14155552671. The ITU defines E.164 as the international public telecommunication numbering plan (ITU E.164).

For in-app chat, invalid identifiers include:

  • Wrong user ID
  • User not imported or registered
  • User deleted or deactivated
  • Using display name instead of account ID
  • Mixing test and production environments
  • Using the wrong SDKAppID or project ID

5. The Message Was Filtered as Spam or Abuse

SMS carriers, messaging apps, and chat platforms all apply anti-abuse protections. Delivery can fail or be silently limited when messages look automated, repetitive, suspicious, or policy-violating.

Common triggers:

  • Sending many identical messages quickly
  • Including suspicious links
  • Using newly created accounts
  • Sending to many recipients with low engagement
  • Missing opt-in for marketing messages
  • Using URL shorteners
  • Sending prohibited content

Business messaging systems increasingly require identity verification, sender registration, and opt-in compliance. If your business messages fail, check the official policy of your provider and the destination country.

6. SMS, MMS, iMessage, or RCS Fallback Is Misconfigured

On phones, “message not delivered” may mean the app tried the wrong transport.

Examples:

  • iMessage is enabled but activation failed.
  • RCS is enabled but the recipient does not support it.
  • SMS fallback is disabled.
  • MMS is disabled for images or group texts.
  • The recipient changed from iPhone to Android without deregistering iMessage.
  • Carrier plan does not support international SMS/MMS.

Apple provides guidance for iMessage activation and SMS/MMS troubleshooting (Apple Support). Google explains how RCS chats work and when messages may use SMS/MMS instead (Google Messages Help).

7. App Permissions or Background Restrictions Are Blocking Delivery

Mobile OS restrictions can delay or prevent message sync.

Check:

  • Notifications are enabled.
  • Background refresh is enabled.
  • Battery optimization is not restricting the app.
  • Data saver is not blocking background data.
  • The app has storage/network permissions where required.
  • Focus mode, Do Not Disturb, or notification summary is not hiding alerts.

This is especially important for Android devices with aggressive manufacturer battery management.

8. The App or Platform Is Experiencing an Outage

A service outage can cause widespread delivery delays. Check the app’s status page if available. For developer platforms, monitor API error rates, WebSocket disconnects, message queue lag, and push notification provider status.

For app teams, create a status dashboard with:

  • Message send success rate
  • Median and p95 delivery latency
  • WebSocket connection success rate
  • Push token registration rate
  • Offline message retrieval success rate
  • Error codes by platform and SDK version

9. The Message Is Too Large or Contains Unsupported Media

Large videos, unsupported file types, or oversized images may fail before delivery.

Common limits vary by platform, but typical problems include:

  • File exceeds upload size limit.
  • Media transcoding fails.
  • MIME type is unsupported.
  • Network times out during upload.
  • Attachment URL expires before recipient opens it.
  • Thumbnail generation fails.

For in-app chat, send media as a structured message: upload the file, receive a stable media URL or file ID, then send the message metadata. Do not send large binary payloads directly through a text messaging channel.

10. Time, Device, or App Version Is Out of Sync

Incorrect device time can break authentication tokens, TLS validation, or SDK login. Old app versions can also use deprecated APIs.

Check:

  • Device date and time are automatic.
  • App is updated.
  • Browser is current.
  • SDK version is supported.
  • TLS certificates are valid.
  • User authentication token has not expired.

For developers using Tencent RTC Chat, invalid or expired UserSig values are a common integration issue. Generate UserSig on a trusted server, not in production client code.

11. Your Chat Backend Did Not Persist or Route the Message

In custom chat systems, a message may vanish after the sender closes the app if you only emit it over WebSocket without persistence.

A production messaging backend should handle:

  • Authentication
  • Conversation membership
  • Message ID generation
  • Message persistence
  • Delivery fanout
  • Offline storage
  • Push notification
  • Retry and deduplication
  • Moderation and audit logs
  • Read receipts and delivery receipts

If you do not want to build this from scratch, Tencent RTC Chat provides managed real-time messaging building blocks with SDKs and APIs for production chat experiences.

12. The Client Treats “Send Success” as “Delivery Success”

This is one of the most common developer mistakes. A successful sendMessage call often means “the server accepted the message,” not “every recipient device displayed it.”

Track separate events:

  • client_send_started
  • client_send_failed
  • server_accepted
  • message_persisted
  • recipient_online_delivered
  • push_sent
  • push_failed
  • recipient_synced
  • read_receipt_received

This separation makes support tickets easier. Instead of saying “message failed,” support can say: “The message was accepted by the server at 10:04:22 UTC, pushed to Android token X, and fetched by the recipient app at 10:07:03 UTC.”

Quick Troubleshooting Checklist for Users

Use this checklist if you are troubleshooting your own phone, desktop app, or browser messaging session.

Step 1: Test Whether the Problem Is Global or Specific

Ask:

  • Can you message other people?
  • Can others message the same recipient?
  • Does the issue happen on Wi-Fi and mobile data?
  • Does it happen only with photos, videos, or group chats?
  • Does it happen only in one app?

If only one recipient is affected, suspect blocking, privacy settings, invalid contact info, or recipient device issues. If every conversation fails, suspect network, account, app, or service outage.

Step 2: Restart the App and Device

This sounds basic, but it clears stale sockets, expired local sessions, and stuck upload tasks.

Do this:

  1. Force close the messaging app.
  2. Turn airplane mode on for 10 seconds.
  3. Turn airplane mode off.
  4. Reopen the app.
  5. Try a short text message before sending media.
  6. Restart the device if the issue persists.

Step 3: Check Connectivity Beyond the Wi-Fi Icon

A full Wi-Fi icon does not guarantee internet access.

Test:

  • Open a website.
  • Switch from Wi-Fi to cellular.
  • Disable VPN temporarily.
  • Try another network.
  • Check whether corporate or school networks block messaging apps.

For browser chat, open DevTools and inspect failed network requests. Look for DNS failures, TLS errors, 401, 403, 429, or 5xx responses.

Step 4: Verify Recipient and Account State

Confirm:

  • The number includes country code.
  • The recipient still uses the app.
  • You are not messaging an old account.
  • The recipient has not disabled messages from unknown users.
  • Your account is not restricted.
  • You completed phone/email verification if required.

Step 5: Send a Plain Text Test

Before troubleshooting media, send a short message like “test.”

If plain text works but media fails, the issue is probably upload size, media encoding, storage permissions, or attachment processing. If text also fails, focus on authentication, network, account state, or routing.

Step 6: Update the App and Operating System

Old builds can break when providers change APIs, certificates, push notification behavior, or security requirements.

Update:

  • Messaging app
  • Browser
  • iOS or Android
  • Carrier settings
  • WebView on Android
  • Desktop app

Step 7: Check Platform-Specific Settings

For iPhone:

  • Check iMessage activation.
  • Enable Send as SMS if you want fallback.
  • Verify SMS/MMS plan with carrier.
  • Check blocked contacts.
  • Confirm date and time are automatic.

For Android:

  • Check RCS status.
  • Enable SMS/MMS fallback.
  • Disable battery optimization for the messaging app.
  • Enable background data.
  • Verify default SMS app if using SMS.

For web apps:

  • Clear site data.
  • Disable extensions.
  • Allow cookies and storage.
  • Check service worker cache.
  • Try incognito mode.
  • Confirm WebSocket traffic is not blocked.

Developer Diagnostic Framework: Sent, Stored, Delivered, Read

If you are building a messaging product, user-facing troubleshooting is not enough. You need an internal delivery model.

Use this framework:

Client -> Auth -> Messaging SDK -> Messaging Service -> Storage
       -> Fanout -> Online Recipient Session
       -> Offline Queue -> Push Provider -> Recipient Device
       -> Recipient App Sync -> Delivery Receipt -> Read Receipt

Message State Model

A robust message state model should include at least:

StateMeaningRetry?Show to sender?
local_pendingMessage created locallyYesClock icon
send_failedClient could not sendYesRetry button
server_acceptedService accepted messageUsually noOne check
storedMessage persistedNoSent
delivered_onlineRecipient online session receivedNoDelivered
push_queuedOffline push requestedMaybeSent
push_failedPush provider rejected tokenMaybeSent, not delivered
recipient_syncedRecipient app pulled messageNoDelivered
readRecipient opened messageNoRead

Do not collapse all of these into one boolean. A single delivered: true flag is not enough for debugging.

At minimum, log:

  • Message ID
  • Sender user ID
  • Conversation ID
  • Recipient user IDs
  • Client platform and SDK version
  • Network type if available
  • Local timestamp and server timestamp
  • API request ID
  • Error code and error message
  • Retry count
  • Push provider response
  • Receipt timestamp

Use privacy-aware logging. Avoid storing message body in plain logs unless your compliance model explicitly permits it.

Delivery SLOs

Define measurable goals:

  • Send API success rate
  • p50 and p95 server acceptance latency
  • p50 and p95 online delivery latency
  • Offline sync success rate
  • Push token registration rate
  • Push rejection rate
  • Message duplication rate

Avoid promising “instant delivery” without defining the measurement point. In real-world networks, offline recipients, OS power management, and push provider behavior all affect timing.

Build a Reliable Chat Send Flow with Tencent RTC

Tencent RTC offers real-time communication products for chat, voice, video, live streaming, conferences, and in-game voice. For this article, the most relevant product is Tencent RTC Chat, which helps developers implement 1:1 chat, group chat, message history, unread counts, rich media, and push notification workflows.

For complete platform guidance, see the Tencent RTC Chat SDK documentation. If your app also needs calling, see the Tencent RTC Call documentation. For live streaming communities, see the Tencent RTC Live documentation.

The key development principle is simple: use SDK callbacks and message IDs to separate send success from delivery, then build retry and support tooling around those events.

Example 1: Initialize Chat and Send a Text Message

The following browser example shows a minimal send flow using the Tencent Cloud Chat SDK. It initializes the SDK, logs in, joins a conversation by user ID, sends a text message, and handles failure.

Install:

npm install @tencentcloud/chat

Create src/chat-send.js:

import TencentCloudChat from '@tencentcloud/chat';

const SDKAppID = Number(import.meta.env.VITE_TRTC_SDK_APP_ID);
const userID = import.meta.env.VITE_TRTC_USER_ID;
const userSig = import.meta.env.VITE_TRTC_USER_SIG;
const peerUserID = import.meta.env.VITE_TRTC_PEER_USER_ID;

const chat = TencentCloudChat.create({ SDKAppID });

chat.setLogLevel(1);

chat.on(TencentCloudChat.EVENT.SDK_READY, async () => {
  console.log('[chat] SDK ready');

  const message = chat.createTextMessage({
    to: peerUserID,
    conversationType: TencentCloudChat.TYPES.CONV_C2C,
    payload: {
      text: 'Hello from Tencent RTC Chat SDK'
    }
  });

  try {
    const result = await chat.sendMessage(message);
    console.log('[chat] server accepted message:', {
      messageID: result.data.message.ID,
      conversationID: result.data.message.conversationID,
      time: result.data.message.time
    });
  } catch (error) {
    console.error('[chat] send failed:', {
      code: error.code,
      message: error.message
    });
  }
});

chat.on(TencentCloudChat.EVENT.MESSAGE_RECEIVED, event => {
  for (const message of event.data) {
    console.log('[chat] received message:', {
      from: message.from,
      id: message.ID,
      payload: message.payload
    });
  }
});

chat.on(TencentCloudChat.EVENT.SDK_NOT_READY, () => {
  console.warn('[chat] SDK not ready');
});

chat.on(TencentCloudChat.EVENT.KICKED_OUT, event => {
  console.warn('[chat] kicked out:', event.data.type);
});

async function main() {
  try {
    await chat.login({ userID, userSig });
    console.log('[chat] login success');
  } catch (error) {
    console.error('[chat] login failed:', {
      code: error.code,
      message: error.message
    });
  }
}

window.addEventListener('beforeunload', () => {
  chat.logout();
});

main();

Create .env.local:

VITE_TRTC_SDK_APP_ID=YOUR_SDKAPPID
VITE_TRTC_USER_ID=alice
VITE_TRTC_USER_SIG=YOUR_GENERATED_USERSIG
VITE_TRTC_PEER_USER_ID=bob

Important debugging notes:

  • If login fails, inspect SDKAppID, userID, and userSig.
  • If send fails with permission or relationship errors, verify user registration and conversation rules.
  • If send succeeds but the recipient does not see the message, inspect recipient login, conversation state, offline sync, and push notification path.
  • Generate production UserSig values on your backend, not in browser code.

Example 2: Add Retry, Idempotency, and Local Pending UI

A message delivery problem often becomes a bad user experience because the UI has no retry state. The next example creates a simple message queue with local pending state and retry support.

import TencentCloudChat from '@tencentcloud/chat';

export class ReliableChatSender {
  constructor({ chat, peerUserID }) {
    this.chat = chat;
    this.peerUserID = peerUserID;
    this.pending = new Map();
  }

  createClientMessageID() {
    return `local_${Date.now()}_${Math.random().toString(16).slice(2)}`;
  }

  async sendText(text) {
    const clientMessageID = this.createClientMessageID();

    const localRecord = {
      clientMessageID,
      text,
      status: 'local_pending',
      retryCount: 0,
      createdAt: new Date().toISOString()
    };

    this.pending.set(clientMessageID, localRecord);
    this.render(localRecord);

    return this.trySend(localRecord);
  }

  async trySend(record) {
    record.status = 'sending';
    record.retryCount += 1;
    this.render(record);

    const message = this.chat.createTextMessage({
      to: this.peerUserID,
      conversationType: TencentCloudChat.TYPES.CONV_C2C,
      payload: {
        text: record.text
      }
    });

    try {
      const result = await this.chat.sendMessage(message);

      const accepted = {
        ...record,
        status: 'server_accepted',
        serverMessageID: result.data.message.ID,
        serverTime: result.data.message.time
      };

      this.pending.set(record.clientMessageID, accepted);
      this.render(accepted);
      return accepted;
    } catch (error) {
      const failed = {
        ...record,
        status: 'send_failed',
        lastErrorCode: error.code,
        lastErrorMessage: error.message
      };

      this.pending.set(record.clientMessageID, failed);
      this.render(failed);
      return failed;
    }
  }

  async retry(clientMessageID) {
    const record = this.pending.get(clientMessageID);

    if (!record) {
      throw new Error(`No pending message found: ${clientMessageID}`);
    }

    if (record.status !== 'send_failed') {
      console.log('Retry skipped because message is not failed:', record.status);
      return record;
    }

    return this.trySend(record);
  }

  render(record) {
    const icon =
      record.status === 'server_accepted' ? '✓' :
      record.status === 'send_failed' ? '!' :
      '…';

    console.log(`[ui] ${icon} ${record.text}`, record);
  }
}

Use it after SDK login:

const sender = new ReliableChatSender({ chat, peerUserID: 'bob' });

document.querySelector('#send').addEventListener('click', async () => {
  const input = document.querySelector('#message');
  await sender.sendText(input.value);
  input.value = '';
});

This pattern prevents a common support issue: users cannot tell whether the message is still sending, failed, or accepted. You can later extend it with delivery receipts, read receipts, and offline replay.

Example 3: Combine Chat with a Tencent RTC Video Call Invitation

Many modern apps use chat and calling together. A user may say “my message is not delivering” when the real issue is that a call invitation, meeting link, or live room notice was not sent.

The example below sends a call invitation as a custom chat message. It can be paired with Tencent RTC Call or the Tencent RTC Call documentation for the actual audio/video session.

import TencentCloudChat from '@tencentcloud/chat';

export async function sendCallInvite({ chat, toUserID, roomID, callType }) {
  const payload = {
    business: 'call_invite',
    version: 1,
    roomID,
    callType, // "audio" or "video"
    createdAt: Date.now()
  };

  const message = chat.createCustomMessage({
    to: toUserID,
    conversationType: TencentCloudChat.TYPES.CONV_C2C,
    payload: {
      data: JSON.stringify(payload),
      description: `${callType} call invitation`,
      extension: 'trtc-call'
    }
  });

  try {
    const result = await chat.sendMessage(message);
    console.log('[call invite] sent:', result.data.message.ID);
    return result.data.message;
  } catch (error) {
    console.error('[call invite] failed:', error.code, error.message);
    throw error;
  }
}

export function handleIncomingCustomMessages(event) {
  for (const message of event.data) {
    if (message.type !== TencentCloudChat.TYPES.MSG_CUSTOM) continue;

    try {
      const data = JSON.parse(message.payload.data);

      if (data.business === 'call_invite') {
        console.log('Incoming call invite:', {
          from: message.from,
          roomID: data.roomID,
          callType: data.callType
        });

        // Show accept/reject UI, then enter the TRTC call room.
      }
    } catch (error) {
      console.warn('Invalid custom message payload:', error);
    }
  }
}

This is also useful for live shopping, education, telehealth, and gaming communities. If your product is a real-time community, you may also want to explore Tencent RTC Live for streaming and Tencent RTC GVoice for in-game voice chat.

Delivery Troubleshooting Matrix by Channel

Different messaging channels fail differently. Use this matrix to focus your debugging.

ChannelTypical delivery signalCommon failure causesBest next step
SMSCarrier accepted, delivered receipt if supportedInvalid number, carrier filtering, roaming, blocked SMS, no balanceVerify E.164 number, test another carrier, check sender registration
MMSMedia sent through carrier MMSFile too large, MMS disabled, carrier unsupportedSend plain SMS, reduce media size
iMessageApple ID/device deliveryActivation, network, recipient switched devices, SMS fallback disabledCheck Apple settings and fallback
RCSRCS chat statusRCS unavailable, carrier support, data disabled, fallback issueCheck RCS status and SMS fallback
WhatsApp-style appsSent/delivered/read checksBlocked, recipient offline, account restricted, app outageTest another contact and network
Web chatWebSocket/API successAuth failure, CORS, blocked WebSocket, expired tokenInspect DevTools network and SDK logs
In-app SDK chatSDK callbacks and message eventsInvalid UserSig, wrong app ID, conversation permissions, push token issueLog SDK errors and server callbacks
Push notificationsAPNs/FCM responseExpired token, disabled notifications, OS throttlingRe-register token and test foreground sync

For a developer team, the most important row is “In-app SDK chat.” A message can be accepted by the chat service but still not notify the user if the push token is expired or notifications are disabled. That does not mean the chat message failed. It means the notification path failed.

How to Debug Message Delivery in Production

A production troubleshooting process should be repeatable. Do not rely on screenshots alone.

Collect the Right Ticket Data

Ask support agents to collect:

  • Sender user ID
  • Recipient user ID
  • Conversation ID
  • Message ID if visible
  • Approximate send time with timezone
  • Sender platform and app version
  • Recipient platform and app version
  • Network type
  • Whether text or media failed
  • Whether other recipients were affected
  • Screenshot of the visible state

Never ask users to send passwords, full authentication tokens, or sensitive message content.

Query by Message ID First

The message ID is your primary key. From it, your internal tools should show:

  • Sender
  • Conversation
  • Server receive time
  • Message type
  • Storage status
  • Fanout status
  • Recipient delivery status
  • Push status
  • Error code
  • Retry attempts

If you cannot query by message ID, add that tool before your next major release. It will reduce support time dramatically.

Correlate Client and Server Time

Mobile devices can have incorrect clocks. Use server timestamps as the source of truth. Client timestamps are still useful for UI ordering, but logs should include both.

Example log shape:

{
  "event": "message_send_result",
  "messageID": "1441152...",
  "clientMessageID": "local_1717000000_abcd",
  "sender": "alice",
  "conversationID": "C2C_bob",
  "clientPlatform": "web",
  "sdkVersion": "chat-js",
  "clientTime": "2026-06-03T10:05:14.100Z",
  "serverTime": "2026-06-03T10:05:14.450Z",
  "status": "server_accepted",
  "errorCode": null
}

Separate Message Delivery from Notification Delivery

A recipient may receive the message only after opening the app. In that case:

  • Message persistence worked.
  • Offline sync worked.
  • Push notification may have failed or been suppressed.

Push notification failure is commonly caused by disabled permissions, expired tokens, OS throttling, low-priority messages, or platform-specific policy. Firebase’s documentation explains how priority and device state affect message handling (Firebase Cloud Messaging).

Watch for Rate Limits and Abuse Controls

If messages fail only during campaigns, launches, or spikes, check rate limits and anti-spam rules.

Look for:

  • 429 responses
  • Sudden increase in rejected messages
  • Similar content repeated at high volume
  • New accounts sending many messages
  • Links triggering filtering
  • Push notification collapse keys replacing older messages

For community or marketplace apps, consider adding moderation, user reputation, and throttling before messages reach the final delivery pipeline.

Comparison: Build Messaging Yourself vs Use a Chat SDK

The “why is my message not delivering” problem becomes harder when you own the full stack. Here is a practical comparison.

RequirementBuild yourselfUse Tencent RTC Chat SDK
1:1 text messagesWebSocket + database requiredBuilt-in SDK workflow
Group chatComplex membership and fanoutGroup conversation support
Offline messagesRequires storage and sync designSupported through managed chat architecture
Push notificationsMust integrate APNs/FCM and token lifecycleCan be integrated with chat workflows
Message historyNeed schema, pagination, retentionSDK/API-supported patterns
Read receiptsNeed receipt protocolAvailable through chat capabilities depending on configuration
ModerationMust design policy and toolingCan be combined with app-side moderation
ScalingNeed queues, shards, fanout strategyManaged service reduces infrastructure burden
DebuggingBuild logs and dashboards yourselfSDK errors and service-side observability patterns
Time to marketSlowerFaster

If chat is not your core infrastructure advantage, using a managed platform usually reduces delivery risk. You can still keep product differentiation in conversation design, AI features, creator workflows, game mechanics, or community experience.

For example:

Common Error Patterns and Fixes

Pattern 1: Message Sends on Desktop but Not Mobile

Likely causes:

  • Mobile token expired
  • App version outdated
  • Mobile network blocked
  • Background data disabled
  • SDK initialization differs between platforms
  • UserSig generated for wrong user ID

Fix:

  1. Compare SDKAppID, user ID, and environment.
  2. Check login success callback on mobile.
  3. Inspect mobile SDK error codes.
  4. Send plain text before media.
  5. Verify push token registration separately.

Pattern 2: Message Sends to One User but Not a Group

Likely causes:

  • Sender is not a group member.
  • Group was deleted.
  • Group message permissions changed.
  • Group muted or restricted.
  • Message triggers moderation.

Fix:

  1. Fetch group profile.
  2. Verify sender role.
  3. Check group message settings.
  4. Try a short plain text message.
  5. Inspect server-side moderation results.

Pattern 3: Message Shows Sent but Recipient Gets It Later

Likely causes:

  • Recipient offline
  • Push notification delayed
  • Battery optimization
  • Recipient app not syncing in background
  • Network transition

Fix:

  1. Confirm message exists in history.
  2. Test recipient foreground app state.
  3. Re-register push token.
  4. Check notification permission.
  5. Measure offline sync latency.

Pattern 4: Images Fail but Text Works

Likely causes:

  • File too large
  • Upload timeout
  • Unsupported format
  • Missing storage permission
  • CDN URL expired
  • Media processing failed

Fix:

  1. Compress image.
  2. Check upload API response.
  3. Validate MIME type.
  4. Send image over a stable network.
  5. Use SDK-supported media message types.

Pattern 5: Messages Fail After Deployment

Likely causes:

  • Wrong environment variables
  • Rotated secret not updated
  • CORS or CSP change
  • SDK version mismatch
  • Backend UserSig generation changed
  • Domain or firewall rules changed

Fix:

  1. Roll back or compare release config.
  2. Verify UserSig generation.
  3. Check auth endpoint status.
  4. Confirm SDKAppID matches environment.
  5. Review CSP, WebSocket, and API allowlists.

Accelerate Integration with MCP

Instead of reading documentation page by page, use Tencent RTC's MCP server to let your AI coding assistant generate integration code directly.

Setup (Cursor / VS Code / Claude Code):

{
  "mcpServers": {
    "tencent-rtc": {
      "command": "npx",
      "args": ["-y", "@tencent-rtc/mcp@latest"],
      "env": {
        "SDKAPPID": "YOUR_SDKAPPID",
        "SECRETKEY": "YOUR_SECRET_KEY"
      }
    }
  }
}

Example prompts you can use:

  • "Create a video calling app using Tencent RTC Web SDK with Vue 3"
  • "Integrate real-time chat into my React app with message history"
  • "Add message retry and delivery-state UI to my existing chat app"
  • "Add live streaming to my existing Express backend"
  • "Generate a secure backend endpoint for UserSig creation"

The MCP server has access to Tencent RTC SDK documentation and can generate working code with your credentials pre-filled. For the full MCP setup guide, see the official MCP documentation.

💡 Pro Tip for AI-assisted development: If you use Cursor or CodeBuddy, the Tencent RTC MCP server (@tencent-rtc/mcp) can scaffold your real-time communication layer in minutes, from project setup to credential generation to working chat or video calls.

Security, Privacy, and Compliance Considerations

Message delivery debugging should not compromise user privacy.

Do Not Log Sensitive Message Bodies by Default

Support teams usually need metadata, not content. Log message IDs, timestamps, delivery states, and error codes. If you must inspect content for abuse or compliance, define a strict access policy, audit trail, and retention period.

Protect UserSig and Secrets

For Tencent RTC integrations, keep secret keys on the server. Client apps should receive short-lived signatures generated by your backend. Do not ship production secret keys in JavaScript, mobile apps, GitHub repositories, or test builds.

Business messaging, marketing messages, and notifications should follow opt-in rules. Users should be able to mute conversations, disable notifications, block accounts, and report abuse.

Handle Deletion and Retention Clearly

Delivery troubleshooting is easier with message history, but privacy regulations may require deletion, export, or retention limits. Define:

  • How long messages are retained
  • How deletion works across devices
  • Whether backups retain deleted messages
  • How audit logs differ from message content
  • What support agents can access

A Practical 30-Minute Debugging Runbook

If you need a fast answer, use this runbook.

Minutes 0–5: Reproduce and Classify

  • Identify sender, recipient, message type, and time.
  • Test another recipient.
  • Test plain text.
  • Test another network.
  • Capture the exact visible status.

Outcome: global issue, recipient-specific issue, media-specific issue, or platform-specific issue.

Minutes 5–10: Check Client State

  • Confirm login/auth success.
  • Check SDK ready state.
  • Inspect network requests.
  • Check WebSocket connection.
  • Check app permissions.
  • Verify device time.

Outcome: client cannot send, or client sends but delivery is uncertain.

Minutes 10–15: Check Server Acceptance

  • Query by message ID.
  • Check API response code.
  • Confirm message persisted.
  • Confirm conversation membership.
  • Check moderation result.

Outcome: server rejected, accepted, or stored the message.

Minutes 15–20: Check Recipient Path

  • Was recipient online?
  • Was fanout attempted?
  • Was push queued?
  • Was push token valid?
  • Did recipient sync message history?

Outcome: online delivery issue, offline sync issue, or push issue.

Minutes 20–25: Check Scale and Policy

  • Look for rate limiting.
  • Check abuse filters.
  • Compare error rates by region.
  • Check platform status.
  • Check recent deployments.

Outcome: systemic issue or isolated issue.

Minutes 25–30: Communicate and Fix

  • Tell the user what happened in plain language.
  • Retry if safe.
  • Ask recipient to reopen app if needed.
  • Patch config or rollback if deployment-related.
  • Create an engineering ticket with message ID and logs.

Key Entities and Concepts

The following entities frequently appear in delivery debugging:

EntityDefinition
Message IDServer or client identifier used to trace a message
Conversation IDIdentifier for a 1:1, group, channel, or room conversation
SenderUser or system account that creates the message
RecipientUser, group, device, or endpoint expected to receive the message
Delivery receiptSignal that the recipient device or app received the message
Read receiptSignal that the recipient opened or viewed the message
Push tokenDevice token used by APNs, FCM, or another push service
UserSigTencent RTC authentication signature used to log in a user
SDKAppIDApplication identifier for a Tencent RTC project
Offline messageMessage stored while recipient is not actively connected
FanoutBackend process that routes one message to one or many recipients
Rate limitProtection that restricts excessive message sending
ModerationPolicy system that detects spam, abuse, or prohibited content
RCSRich Communication Services, a carrier-supported messaging upgrade from SMS
E.164International phone number format used for global routing

Clear naming reduces debugging confusion. A “failed notification” is not the same as a “failed message.” A “server-accepted message” is not always a “recipient-delivered message.”

When to Escalate to Engineering or Your Provider

Escalate when:

  • Multiple users report delivery failures at the same time.
  • The same error code appears across clients.
  • Messages disappear from history.
  • Delivery latency suddenly increases.
  • Push rejection rate spikes.
  • A recent deployment changed auth, SDK, or network behavior.
  • Payments, safety, healthcare, education, or compliance workflows depend on the message.

Include:

  • Message ID
  • Conversation ID
  • User IDs
  • UTC timestamps
  • Platform and SDK version
  • Error code
  • Reproduction steps
  • Screenshots
  • Recent release version
  • Network logs if available

If you use Tencent RTC, include relevant SDK logs and configuration details when contacting support. Also verify your implementation against the Tencent RTC SDK download and documentation hub.

FAQ

Why is my message not delivering to one person?

If messages fail only for one person, the most likely causes are blocking, recipient privacy settings, invalid contact details, recipient offline status, or that user’s app/device issue. Test another contact and send a plain text message to narrow it down.

Why does my message say sent but not delivered?

“Sent” usually means your app or server accepted the message. “Delivered” usually means the recipient’s device or app received it. The recipient may be offline, push notifications may be disabled, or the app may not have synced yet.

Why are my SMS messages not delivering?

SMS can fail because of invalid phone numbers, carrier filtering, blocked numbers, roaming issues, insufficient plan support, or international routing problems. Use E.164 number format and test with another carrier or recipient.

Why are iMessage or RCS messages not delivering?

iMessage may fail because of activation, Apple ID, network, or SMS fallback settings. RCS may fail because the recipient or carrier does not support RCS, data is unavailable, or fallback is disabled. Check Apple or Google Messages settings.

Why do chat app messages deliver late?

Late delivery often means the recipient was offline, push notifications were delayed, the device restricted background activity, or the app synced only after being reopened. For developers, measure offline sync latency and push token health.

How do developers know whether a message was really delivered?

Developers should track separate states: local pending, send failed, server accepted, stored, pushed, recipient synced, delivered, and read. Do not treat a successful send API response as proof of recipient delivery.

Yes. SMS carriers, messaging platforms, and chat apps may filter suspicious links, repeated content, URL shorteners, or spam-like campaigns. If plain text works but linked messages fail, review anti-abuse rules and sender reputation.

What is the fastest way to build reliable in-app chat?

Use a managed chat SDK, implement clear message states, add retries, persist messages, monitor push notifications, and log delivery events by message ID. You can start with Tencent RTC Chat and the Free Chat API.

Conclusion: Fix the Delivery Stage, Not Just the Symptom

When you ask “why is my message not delivering,” do not stop at the error label. Find the exact stage where delivery breaks: sender network, platform acceptance, backend storage, recipient routing, push notification, recipient sync, or read receipt.

For users, the best first steps are to test another recipient, switch networks, send plain text, update the app, and check platform-specific SMS, iMessage, RCS, or notification settings.

For developers, the best long-term fix is instrumentation. Track message IDs, state transitions, SDK errors, push results, and recipient sync. Build retry UI so users understand whether a message is pending, failed, sent, delivered, or read.

If you are building real-time chat, start with Tencent RTC Chat, review the Tencent RTC Chat SDK documentation, and use Tencent RTC MCP to scaffold integration faster. For apps that combine chat with voice, video, live streaming, or gaming, explore Tencent RTC Call, Tencent RTC Live, and Tencent RTC GVoice as your next steps.

Author: Maya Chen, senior developer content writer focused on real-time communication, chat architecture, and developer experience.