Skip to content

New: BD, IN and PK Voice OTP capacity now live, test routes issued same day.

SMPP Error Codes Explained

What the common SMPP command_status values actually mean, which ones are your fault, which are the supplier's, and what to do about each.

We write about A2P SMS Compliance Integration Voice OTP VoIP
Illustration of an SMPP submit response returning a command status error code

When an SMPP submit fails, the SMSC returns a command_status value in the submit_sm_resp PDU. Those values are defined in the SMPP specification, and most integration problems are one of about a dozen of them. Knowing which are your fault and which are the supplier’s saves a great deal of time.

How to read a command_status

The value is a four-byte integer, usually written in hex. 0x00000000 is ESME_ROK, the SMSC accepted the submission. Anything else is a rejection, and the message never entered the network.

Two things to keep straight. First, a successful submit_sm_resp means accepted for delivery, not delivered, delivery is reported later in a receipt. Second, values from 0x00000400 upward are vendor-specific, so a code in that range needs your supplier’s documentation rather than the specification.

Bind and session errors

0x0000000D ESME_RBINDFAIL, the bind was rejected. Usually credentials, but also a system_id already bound elsewhere, or an address_range mismatch. Check whether you are exceeding your permitted number of concurrent binds before assuming the password is wrong.

0x0000000E ESME_RINVPASWD and 0x0000000F ESME_RINVSYSID, wrong password, wrong system_id. Note that some SMSCs deliberately return the generic bind failure instead, to avoid confirming which half is correct.

0x00000005 ESME_RALYBND, already bound. Your client is attempting a second bind on a session that is already established, typically after a reconnect where the old session was not cleanly closed.

0x00000004 ESME_RINVBNDSTS, the command is not valid for this bind type. Sending a submit_sm on a receiver-only bind produces this.

Addressing errors

0x0000000B ESME_RINVDSTADR, invalid destination address. Almost always a formatting problem on your side: missing country code, a leading plus where the SMSC wants international format without one, or a mismatch between the number and the ton/npi values you set. Fix the number format before escalating.

0x0000000A ESME_RINVSRCADR, invalid source address. Your sender ID is malformed for the configured type: too long for alphanumeric, non-numeric characters where a numeric address is expected, or an unregistered sender ID on a route that requires registration.

Content errors

0x00000001 ESME_RINVMSGLEN, invalid message length. The payload exceeds what the field allows. Long messages need either concatenation via UDH or the message_payload optional parameter; check which your supplier expects.

0x00000003 ESME_RINVCMDID, the SMSC does not support the operation you sent. Common when using data_sm against a platform that only accepts submit_sm.

0x00000067 ESME_RINVDCS, invalid data coding scheme. Usually a wrong value for Unicode. UCS-2 is normally 0x08; sending Unicode content with a GSM-7 DCS produces unreadable messages when it does not produce this error.

Throttling and capacity

0x00000058 ESME_RTHROTTLED; you are submitting faster than the bind permits. This is the healthy way for a platform to push back. Back off, retry with a delay, and treat a sustained rate of these as a signal to review your provisioned TPS rather than to retry harder.

0x00000014 ESME_RMSGQFUL, the SMSC queue is full. Usually the supplier’s side, and usually temporary. Persistent occurrences are worth raising.

Permission and account errors

0x00000045 ESME_RSUBMITFAIL, a general submit failure. Frustratingly vague; it often means the platform rejected the message for a reason it does not want to enumerate, such as a routing rule or a content filter. Ask the supplier for the underlying reason.

0x00000088 ESME_RINVOPTPARAMVAL, an optional parameter has a bad value. Check any TLVs you are setting.

Account balance and routing rejections are frequently returned as vendor-specific codes above 0x00000400, which is why the supplier’s error list matters as much as the specification.

Practical debugging order

  1. Confirm it is a submit rejection and not a delivery failure; they are different problems with different owners.
  2. If the code is above 0x00000400, go straight to the supplier’s documentation.
  3. For addressing and content errors, reproduce with a single hand-built PDU before touching production code.
  4. Log the full command_status, your ton/npi, the DCS, and the raw payload length for every rejection. Without those four fields a support ticket is guesswork.
  5. If the code is generic, ask the supplier for the internal reason. Good platforms have one.

Connection details for both paths: SMPP v3.4 bind and HTTP REST API. Related reading: choosing between them.

Share

Keep reading

Related insights

Integration

SMS Delivery Receipts and Fake DLRs

A delivery receipt is a claim, not proof. How DLRs are generated, what the status fields mean, and the patterns that show…

4 min read
Integration

SMPP Throughput: Planning TPS and Binds

Why a bind rated at 100 TPS does not give you 100 messages per second, how the window size governs real throughput,…

4 min read

Start in 24 hours

Test a live route before you commit a single dollar

Send us your destinations and traffic profile. We return a costed route plan and a free test account, usually the same business day.

Chat on WhatsApp