SMPP Error Codes — Complete Reference
Every SMPP command status code from the SMPP v3.4 and v5.0 specifications, plus DLR delivery report statuses and common vendor-specific codes. Click any hex code to copy it to your clipboard. Use the search box and category filters to find codes quickly.
What is SMPP?
SMPP (Short Message Peer-to-Peer) is the standard protocol used by the SMS industry for exchanging messages between SMSCs (Short Message Service Centers) and ESMEs (External Short Messaging Entities). It operates over TCP/IP and uses a binary PDU (Protocol Data Unit) format. The most widely deployed versions are SMPP v3.4 (1999) and SMPP v5.0 (2003).
Understanding Command Status
Every SMPP response PDU contains a command_status field (4 bytes). A value of 0x00000000 means success. Non-zero values indicate an error. The hex code is divided into ranges: 0x0001-0x00FF for standard protocol errors, 0x0100-0x03FF for extended spec errors, and 0x0400+ for vendor-specific errors.
Delivery Reports (DLR)
When registered_delivery is set, the SMSC sends a deliver_sm PDU with a delivery receipt in the message body. The stat: field contains the DLR status (DELIVRD, UNDELIV, EXPIRED, etc.). DLR formats vary by SMSC vendor, but the status codes listed below are standard across the industry.
Vendor-Specific Codes
SMPP reserves codes 0x00000400 and above for vendor-defined errors. Major platforms like Logica/Mavenir, Huawei, Nokia, Sinch, Infobip, and Twilio define their own codes in this range. The vendor codes listed here represent commonly encountered values across the industry.
No matching SMPP codes found. Try a different search term.
SMPP Quick Reference
SMPP Bind Types
bind_transmitter | Send messages only (submit_sm) |
bind_receiver | Receive messages only (deliver_sm) |
bind_transceiver | Send and receive on same session |
Most modern implementations use bind_transceiver for simplicity. The SMSC must support the chosen bind type.
Common SMPP Operations
submit_sm | Submit a message for delivery |
deliver_sm | Deliver a message or DLR to ESME |
query_sm | Query the status of a message |
cancel_sm | Cancel a previously submitted message |
replace_sm | Replace a pending message |
enquire_link | Keep-alive / heartbeat check |
unbind | Gracefully close the SMPP session |
Data Coding Scheme Values
0x00 | SMSC Default Alphabet (usually GSM 7-bit) |
0x01 | IA5 / ASCII |
0x03 | Latin-1 (ISO-8859-1) |
0x04 | 8-bit binary (Octet unspecified) |
0x05 | JIS (X 0208-1990) |
0x06 | Cyrillic (ISO-8859-5) |
0x07 | Latin/Hebrew (ISO-8859-8) |
0x08 | UCS2 / UTF-16BE (Unicode) |
0x0D | Extended Kanji JIS |
0x0E | KS C 5601 (Korean) |
TON (Type of Number) Values
0x00 | Unknown |
0x01 | International (E.164 with country code) |
0x02 | National (without country code) |
0x03 | Network Specific |
0x04 | Subscriber Number |
0x05 | Alphanumeric (sender ID text) |
0x06 | Abbreviated |
For international numbers, use TON=1 with NPI=1. For alphanumeric sender IDs, use TON=5 with NPI=0.
NPI (Numbering Plan) Values
0x00 | Unknown |
0x01 | ISDN / E.164 (telephone numbering) |
0x03 | Data / X.121 |
0x04 | Telex / F.69 |
0x06 | Land Mobile / E.212 |
0x08 | National |
0x09 | Private |
0x0A | ERMES |
0x0E | Internet (IP) |
0x12 | WAP Client Id |
SMPP Time Format
| Absolute | YYMMDDhhmmsstnnp |
| Relative | YYMMDDhhmmss000R |
Example: 260406120000004+ = April 6, 2026 12:00:00 UTC+1. 000001000000000R = relative 1 day from now. The t field is tenths of second, nn is the quarter-hour UTC offset, p is + or - or R (relative).
Frequently Asked Questions
What is the most common SMPP error code?
0x00000045 (ESME_RSUBMITFAIL) and 0x00000058 (ESME_RTHROTTLED) are among the most frequently encountered errors. Submit failures can have many underlying causes, while throttling errors indicate you are sending faster than your allowed rate. Always implement proper rate limiting and exponential backoff in your SMPP client.
What does ESME_RSYSERR (0x00000008) mean?
This is a generic system error from the SMSC. It can mean almost anything went wrong on the server side. If you see this repeatedly, contact your SMSC provider with timestamps and message IDs so they can check their server logs. A single occurrence can usually be resolved by retrying.
How do I handle ESME_RTHROTTLED?
When you receive error 0x00000058, your ESME is exceeding the configured messages-per-second (MPS) limit. Implement a sliding window rate limiter in your application. Use exponential backoff: wait 1s, then 2s, then 4s between retries. Never immediately retry a throttled message as this will worsen the problem.
What is the difference between DLR statuses UNDELIV and EXPIRED?
UNDELIV means permanent failure — the message cannot be delivered (number inactive, subscriber barred, etc.). EXPIRED means the SMSC tried to deliver within the validity period but the phone was unreachable (turned off, no signal) the entire time. EXPIRED messages might succeed if resubmitted when the phone is back online.
Are vendor-specific error codes (0x0400+) standardized?
No. The SMPP specification reserves codes 0x00000400 and above for vendor use, but each SMSC vendor defines their own meanings. A code that means "destination blocked" on one platform might mean something entirely different on another. Always refer to your specific SMSC provider's documentation for codes in this range.
What SMPP version should I use?
SMPP v3.4 is the most widely deployed version and is supported by virtually all SMSCs. SMPP v5.0 adds features like broadcast messaging and additional TLVs but has limited adoption. Unless you specifically need v5.0 features (cell broadcast, enhanced status reporting), use v3.4 for maximum compatibility.
How do I troubleshoot ESME_RBINDFAIL (0x0000000D)?
Bind failures are usually caused by: (1) Wrong system_id or password, (2) IP not whitelisted on the SMSC, (3) Account disabled or expired, (4) Maximum concurrent binds exceeded, (5) Wrong SMPP port. Verify your credentials, check firewall rules, and ensure your IP is authorized with the SMSC operator.
What is the enquire_link PDU used for?
The enquire_link PDU serves as a heartbeat / keep-alive mechanism. Both the ESME and SMSC can send it to verify the TCP connection is still alive. If no response (enquire_link_resp) is received within the configured timeout (typically 30-60 seconds), the session is considered dead and should be re-established. Most implementations send enquire_link every 30-60 seconds during idle periods.
What is the maximum message length in SMPP?
The short_message field in submit_sm supports up to 254 bytes. For GSM 7-bit encoding, this allows 160 characters per segment. For UCS-2 (Unicode), 70 characters per segment. For longer messages, use the message_payload TLV which supports up to 64KB, or implement UDH-based message concatenation (multi-part SMS) with up to 255 segments.
How do I read a delivery receipt (DLR) message?
A typical DLR in the deliver_sm short_message field looks like: id:12345 sub:001 dlvrd:001 submit date:2604061200 done date:2604061201 stat:DELIVRD err:000 text:.... The key field is stat: which contains the DLR status code (DELIVRD, UNDELIV, EXPIRED, etc.). The id: field matches the message_id from the original submit_sm_resp. Note that DLR format varies between SMSC vendors.