Search codes and states
Filters both tables below as you type. Accepts hex (0x...), decimal, or any part of a code name / stat token. Nothing is sent anywhere — this runs entirely in your browser.
SMPP 3.4 command_status error codes
These are the command_status values a submit_sm_resp, bind_resp, or other SMPP response PDU can return, exactly as documented in the SMPP 3.4 specification. Codes outside this list (including the 0x400–0x4FF range) are vendor-specific — see the note below the table.
Showing 48 of 48
| Code | Constant | Meaning | What to check |
|---|---|---|---|
0x00000000dec 0 | ESME_ROK | No Error | Success acknowledgment; nothing to fix. Confirms the previous PDU was accepted. |
0x00000001dec 1 | ESME_RINVMSGLEN | Message Length is invalid | Check the short_message length field matches the actual payload and doesn't exceed the SMSC's configured max (use the message_payload TLV for long messages). |
0x00000002dec 2 | ESME_RINVCMDLEN | Command Length is invalid | The PDU's declared command_length doesn't match the actual byte count sent; check your PDU encoder for off-by-one or field-size bugs. |
0x00000003dec 3 | ESME_RINVCMDID | Invalid Command ID | command_id doesn't match a value the SMSC recognizes; verify you're sending a supported SMPP 3.4 operation. |
0x00000004dec 4 | ESME_RINVBNDSTS | Incorrect BIND Status for given command | You sent an operation (e.g. submit_sm) before completing a bind, or used the wrong bind type (TX/RX/TRX) for that operation. |
0x00000005dec 5 | ESME_RALYBND | ESME Already in Bound State | A second bind_* was sent on a session that's already bound; only bind once per connection. |
0x00000006dec 6 | ESME_RINVPRTFLG | Invalid Priority Flag | priority_flag value is outside the 0-3 range the SMSC accepts. |
0x00000007dec 7 | ESME_RINVREGDLVFLG | Invalid Registered Delivery Flag | registered_delivery doesn't match one of the defined bitmask combinations; check the spec table for valid values. |
0x00000008dec 8 | ESME_RSYSERR | System Error | Failure on the SMSC side unrelated to your PDU; retry with backoff and check SMSC status with your provider if persistent. |
0x0000000Adec 10 | ESME_RINVSRCADR | Invalid Source Address | source_addr, source_addr_ton, or source_addr_npi don't form a valid combination; confirm your sender ID/number format matches what the SMSC expects. |
0x0000000Bdec 11 | ESME_RINVDSTADR | Invalid Dest Addr | Malformed destination number; verify E.164 formatting and that dest_addr_ton/npi match the number type. |
0x0000000Cdec 12 | ESME_RINVMSGID | Message ID is invalid | The message_id referenced in a query_sm/cancel_sm/replace_sm doesn't exist or has expired on the SMSC. |
0x0000000Ddec 13 | ESME_RBINDFAIL | Bind Failed | Generic bind rejection; check system_id/password/system_type and that your IP is allowlisted if the SMSC restricts by source. |
0x0000000Edec 14 | ESME_RINVPASWD | Invalid Password | Credentials rejected; confirm the password field and any case-sensitivity/length limits with your provider. |
0x0000000Fdec 15 | ESME_RINVSYSID | Invalid System ID | system_id (account/username) not recognized by the SMSC. |
0x00000011dec 17 | ESME_RCANCELFAIL | Cancel SM Failed | The message may already be delivered, expired, or the message_id/source no longer matches; cancel windows are often short. |
0x00000013dec 19 | ESME_RREPLACEFAIL | Replace SM Failed | Same constraints as cancel: the message is likely already sent, or the identifying fields don't match the original submit. |
0x00000014dec 20 | ESME_RMSGQFUL | Message Queue Full | SMSC-side throttling/capacity limit; back off and retry, and check your contracted throughput (TPS) against what you're sending. |
0x00000015dec 21 | ESME_RINVSERTYP | Invalid Service Type | service_type isn't one the SMSC recognizes; leave it as an empty string unless your provider requires a specific value. |
0x00000033dec 51 | ESME_RINVNUMDESTS | Invalid number of destinations | number_of_dests in submit_multi is 0, negative, or exceeds the SMSC's per-request limit. |
0x00000034dec 52 | ESME_RINVDLNAME | Invalid Distribution List name | The named list in submit_multi doesn't exist on the SMSC. |
0x00000040dec 64 | ESME_RINVDESTFLAG | Destination flag is invalid | dest_flag in a submit_multi destination entry isn't a recognized SME/distribution-list flag. |
0x00000042dec 66 | ESME_RINVSUBREP | Invalid 'submit with replace' request | replace_if_present_flag is combined with fields that don't identify a valid prior message. |
0x00000043dec 67 | ESME_RINVESMCLASS | Invalid esm_class field data | esm_class bits conflict (e.g. requesting a DLR-only message type with an invalid messaging mode); check the bitmask against the spec. |
0x00000044dec 68 | ESME_RCNTSUBDL | Cannot Submit to Distribution List | The account/bind isn't permitted to submit to distribution lists, or the list is empty/disabled. |
0x00000045dec 69 | ESME_RSUBMITFAIL | submit_sm or submit_multi failed | Generic submission failure; check the SMSC's logs or resp fields for a more specific reason if your provider surfaces one. |
0x00000048dec 72 | ESME_RINVSRCTON | Invalid Source address TON | Type-of-number for the sender doesn't match the actual source_addr format (e.g. an alphanumeric sender ID sent with an international TON). |
0x00000049dec 73 | ESME_RINVSRCNPI | Invalid Source address NPI | Numbering-plan-indicator for the sender is inconsistent with the source_addr value. |
0x00000050dec 80 | ESME_RINVDSTTON | Invalid Destination address TON | dest_addr_ton doesn't match the destination number format. |
0x00000051dec 81 | ESME_RINVDSTNPI | Invalid Destination address NPI | dest_addr_npi doesn't match the destination numbering plan. |
0x00000053dec 83 | ESME_RINVSYSTYP | Invalid system_type field | system_type sent at bind isn't one the SMSC accepts; confirm the exact value with your provider (often left blank). |
0x00000054dec 84 | ESME_RINVREPFLAG | Invalid replace_if_present flag | Value is outside the defined 0/1 range. |
0x00000055dec 85 | ESME_RINVNUMMSGS | Invalid number of messages | Exceeds the SMSC's allowed message count for the operation; this limit is provider-defined. |
0x00000058dec 88 | ESME_RTHROTTLED | Throttling error | You're exceeding your contracted TPS (transactions per second); add a client-side rate limiter and exponential backoff instead of retrying immediately. |
0x00000061dec 97 | ESME_RINVSCHED | Invalid Scheduled Delivery Time | schedule_delivery_time isn't in valid SMPP time format, or is set in the past. |
0x00000062dec 98 | ESME_RINVEXPIRY | Invalid message validity period | validity_period is malformed or exceeds the SMSC's max validity window. |
0x00000063dec 99 | ESME_RINVDFTMSGID | Predefined Message Invalid or Not Found | sm_default_msg_id references a template that doesn't exist on the SMSC. |
0x00000064dec 100 | ESME_RX_T_APPN | ESME Receiver Temporary App Error Code | The receiving ESME (your app) returned a temporary error while handling an inbound PDU; check your listener's response handling. |
0x00000065dec 101 | ESME_RX_P_APPN | ESME Receiver Permanent App Error Code | Same as above but flagged permanent; your app rejected the message and it likely won't be retried. |
0x00000066dec 102 | ESME_RX_R_APPN | ESME Receiver Reject Message Error Code | Your app explicitly rejected the inbound message. |
0x00000067dec 103 | ESME_RQUERYFAIL | query_sm request failed | The queried message_id is unknown, expired, or the query itself was malformed. |
0x000000C0dec 192 | ESME_RINVOPTPARSTREAM | Error in the optional part of the PDU Body | Malformed TLV stream; check TLV tag/length/value encoding for truncation or misalignment. |
0x000000C1dec 193 | ESME_ROPTPARNOTALLWD | Optional Parameter not allowed | A TLV was included that isn't valid for this PDU type; remove it or check the spec's per-PDU TLV table. |
0x000000C2dec 194 | ESME_RINVPARLEN | Invalid Parameter Length | A TLV's declared length doesn't match its actual value length. |
0x000000C3dec 195 | ESME_RMISSINGOPTPARAM | Expected Optional Parameter missing | A mandatory-for-this-context TLV wasn't included (e.g. a provider requiring message_payload for long messages). |
0x000000C4dec 196 | ESME_RINVOPTPARAMVAL | Invalid Optional Parameter Value | A TLV's value is outside the range/format the SMSC expects for that tag. |
0x000000FEdec 254 | ESME_RDELIVERYFAILURE | Delivery Failure (data_sm_resp) | Used specifically in data_sm_resp to report an immediate delivery failure rather than success; check the accompanying network_error_code TLV if your provider sends one. |
0x000000FFdec 255 | ESME_RUNKNOWNERR | Unknown Error | Catch-all for failures the SMSC doesn't map to a specific code; check provider-side logs for detail. |
DLR delivery states & stat: tokens
Once a message is submitted, the SMSC reports back a final (or intermediate) delivery status — either as a numeric message_state in a deliver_sm/query_sm_resp, or as a short stat: token inside the DLR's text body (the de facto convention most SMSCs use, per the SMPP appendix). Both refer to the same set of states.
Showing 8 of 8
| State & stat: token | Meaning | Typical cause | What to do |
|---|---|---|---|
1 · ENROUTEstat:ENROUTE | Message is in the process of being delivered by the SMSC/carrier. | Normal transit state before a final status is reached. | No action needed yet — wait for a final state before treating this as a failure. |
2 · DELIVEREDstat:DELIVRD | Message was delivered to the handset (or the carrier confirmed delivery to the SMSC). | Successful delivery. | Log as success. |
3 · EXPIREDstat:EXPIRED | The message's validity_period elapsed before it could be delivered. | Handset off, out of coverage, or roaming for longer than the validity window. | Check whether validity_period is long enough for your audience's typical downtime; see the debugging flow below. |
4 · DELETEDstat:DELETED | Message was deleted from the SMSC queue before delivery. | Usually manual cancellation or an SMSC-side queue purge. | Rare in normal operation; contact your provider if you see this at volume. |
5 · UNDELIVERABLEstat:UNDELIV | The SMSC/carrier determined the message cannot be delivered. | Invalid or disconnected number, blocked sender ID, or a carrier-side rejection. | Validate the destination number and check sender-ID rules for that country before resubmitting; see the debugging flow below. |
6 · ACCEPTEDstat:ACCEPTD | Message was accepted by an intermediate system, used on networks with manual/legacy delivery acknowledgment. | Provider- and network-specific acknowledgment step. | Check your provider's DLR documentation for what triggers ACCEPTD versus DELIVRD on their routes. |
7 · UNKNOWNstat:UNKNOWN | The SMSC has no definite delivery status for the message. | Status not yet available, or the query window has elapsed. | Retry the status query later; don't treat this as a hard failure on its own. |
8 · REJECTEDstat:REJECTD | Message was rejected by the SMSC or a downstream carrier before it entered delivery. | Content filtering, a blocked sender ID, or an account/route restriction. | Check the message content and sender ID against the destination carrier's filtering rules. |
Codes in 0x00000400–0x000004FF, and any other codes outside the documented SMPP 3.4 command_status list above, are vendor-specific extensions. Their meanings vary by SMSC vendor and by provider — there is no universal table for them. Check your specific provider's API documentation for anything in that range; this page intentionally does not guess at vendor-specific meanings.
Common debugging flows
Three situations that come up constantly when reading SMPP/DLR output, and the honest, minimal fix for each.
ESME_RTHROTTLED — respect TPS, don't hammer retries
- Confirm your contracted TPS.Check the transactions-per-second limit your provider has actually given your account — it's usually in your onboarding docs or dashboard, not a guess.
- Measure your real send rate.Log actual submit_sm calls per second and compare against the contracted limit; bursty sending (e.g. all messages fired in a tight loop) can trip throttling even if your average rate is fine.
- Add a rate limiter and backoff, not a retry loop.Use a token bucket or fixed-interval queue to stay under the TPS ceiling, and apply exponential backoff on repeated ESME_RTHROTTLED responses instead of resubmitting immediately.
DLR comes back UNDELIV with a permanent-looking error
- Check the submit_sm_resp command_status first.If it wasn't ESME_ROK, the message never reached the SMSC queue at all — that's a separate problem from the DLR state, and the DLR you're looking at may be stale or unrelated.
- If submit succeeded but the DLR says UNDELIV, validate the number.Confirm the destination is correctly formatted (E.164), still live, and not on a do-not-deliver list; also check whether your sender ID is allowed for that destination country.
- Don't blindly retry the same combination.Resubmitting an UNDELIV message with the same number and sender ID usually reproduces the same result; fix the underlying validity or sender-ID issue first.
DLR comes back EXPIRED
- Check your validity_period against real handset behavior.A short validity window will expire before a phone that's off or roaming reconnects; compare your setting against how long your audience is typically unreachable.
- Distinguish EXPIRED from UNDELIV.EXPIRED means the SMSC kept trying until the validity window ran out; UNDELIV means the carrier actively rejected it. They point to different fixes — don't treat them the same.
- Watch for a pattern by country or carrier.If EXPIRED clusters on specific destinations, consider lengthening validity_period for those routes rather than assuming it's a routing or content problem.
Frequently asked questions
What does ESME_RTHROTTLED mean?
ESME_RTHROTTLED is SMPP command_status 0x00000058 (decimal 88). It means you're exceeding your contracted TPS (transactions per second) with the SMSC. The fix is a client-side rate limiter and exponential backoff on retries, not immediately resending at the same rate.
What does UNDELIV mean in a DLR?
UNDELIV is the short stat: token for DLR message state 5, UNDELIVERABLE. It means the SMSC or a downstream carrier determined the message cannot be delivered, typically because of an invalid or disconnected number, a blocked sender ID, or a carrier-side rejection. Validate the destination number and sender-ID rules for that country before resubmitting.
What is DLR message state ENROUTE?
ENROUTE is DLR message state 1. It means the message is still in the process of being delivered by the SMSC or carrier and hasn't reached a final state yet. It is not an error — wait for a final state (DELIVRD, EXPIRED, UNDELIV, etc.) before treating a message as failed.
Are vendor-specific SMPP error codes covered here?
No. This page covers only the command_status codes documented in the SMPP 3.4 specification. Codes in the 0x00000400-0x000004FF range, and any other vendor-specific extension ranges, are defined by individual SMSC vendors and vary by provider — check your specific provider's documentation for those.