BroadNet
SMPPErrors

SMPP command_status error codes

Updated 2 min readStandards-based
Direct answer

command_status is the 4-byte header field that reports the outcome of an operation. In a request it is 0 (ESME_ROK); in a response it carries an ESME_R* error code. 0x00000000 is success; non-zero values indicate specific faults such as invalid password, throttling, or a full message queue.

§01

How command_status works

Every response PDU echoes the request's sequence_number and sets command_status to the result. ESME_ROK (0) means success. Any other value is an error whose numeric code maps to a named ESME_R* constant in the spec. Codes 0x00000100–0x000003FF are reserved for SMPP extensions and 0x00000400–0x000004FF for SMSC-vendor-specific errors, so always handle unknown codes gracefully.

§02

The codes you will actually see

A small set of codes covers most real-world handling. Group them by response: retry-after-backoff (throttling, queue full, system error), fix-the-request (invalid address, TON/NPI, data_coding, message length), and fatal-for-the-session (invalid password or system id, bind failure).

Frequently encountered command_status codes
ValueNameMeaningTypical reaction
0x00000000ESME_ROKNo errorSuccess
0x00000001ESME_RINVMSGLENInvalid message lengthFix payload / segment
0x00000005ESME_RALYBNDAlready boundDo not re-bind; reuse session
0x0000000AESME_RINVSRCADRInvalid source addressFix sender / TON / NPI
0x0000000BESME_RINVDSTADRInvalid destination addressFix recipient MSISDN
0x0000000DESME_RBINDFAILBind failedBack off, check credentials
0x0000000EESME_RINVPASWDInvalid passwordFatal — fix credentials
0x0000000FESME_RINVSYSIDInvalid system IDFatal — fix credentials
0x00000014ESME_RMSGQFULMessage queue fullBack off and retry
0x00000043ESME_RINVESMCLASSInvalid esm_classFix esm_class bits
0x00000058ESME_RTHROTTLEDThrottling — rate exceededSlow down, back off with jitter
0x00000062ESME_RINVEXPIRYInvalid validity_periodFix validity format
0x000000FEESME_RDELIVERYFAILUREDelivery failure (data_sm)Inspect / retry per policy
0x000000FFESME_RUNKNOWNERRUnknown errorLog, alert, retry cautiously
§03

Reserved and vendor ranges

Not every code you receive is in the core spec. The spec reserves 0x00000100–0x000003FF for future SMPP use and 0x00000400–0x000004FF for SMSC-specific codes, so your provider may return a value only their documentation explains. Map provider-specific codes to a normalised internal taxonomy (invalid number, blocked, throttled, temporary failure) so cross-route quality stays comparable.

command_status reserved ranges
RangeReserved for
0x00000100 – 0x000003FFSMPP protocol extensions
0x00000400 – 0x000004FFSMSC vendor-specific errors
0x00000500 – 0xFFFFFFFFReserved
FAQ

Frequently asked

What does ESME_RTHROTTLED mean and how should I handle it?

ESME_RTHROTTLED (0x00000058) means you exceeded your allowed message rate. Stop increasing load, pause submits, and back off with jitter before retrying. Persisting at the same rate risks the provider dropping the bind.

Is ESME_RINVPASWD recoverable?

No, not at runtime. ESME_RINVPASWD (0x0000000E) indicates wrong credentials. Do not hot-loop the bind; fix the system_id/password configuration and reconnect. Repeated failed binds can trigger IP blocking.

What is the difference between ESME_RMSGQFUL and ESME_RTHROTTLED?

ESME_RMSGQFUL (0x00000014) means the SMSC's queue is temporarily full; ESME_RTHROTTLED (0x00000058) means you exceeded your rate limit. Both call for backoff, but throttling is about your TPS while queue-full is about the SMSC's capacity.

I received an error code that is not in the spec — why?

SMPP reserves 0x400–0x4FF for SMSC-vendor-specific codes, so your provider may return a value documented only by them. Consult the provider's error table and map it to your internal taxonomy.

References

Source specifications

The published standards this page is grounded in. Opens in a new tab.

BNMaintained by the BroadNet engineering team·Carrier-grade messaging since 2003
Put it on the wire

Build with a real SMPP bind and REST API.

Request test access with real test keys: send to your own verified number first, then move to production across 200+ countries once your sender identity and routes are approved.