Troubleshooting Guide
Troubleshooting Guide
This guide covers common issues and diagnostic procedures for the SMS Gateway Proxy platform.
Quick Health Check
Before investigating specific issues, verify the overall system state:
# 1. Check proxy health
curl http://localhost:8080/healthy
# Expected: {"status": "ok"}
# 2. Check SMPP links
curl http://localhost:8080/api/v1/dashboard/smpp-links
# Shows state of all configured SMPP connections
# 3. Check system statistics
curl http://localhost:8080/api/v1/dashboard/stats
# Shows current RPS, message counts, error rates
# 4. Check Prometheus metrics
curl http://localhost:8080/metrics
# Full metrics dump for detailed analysis
If /healthy does not return {"status": "ok"}, the proxy service itself may be down — check Docker container status with docker compose ps.
SMPP Connection Issues
Link shows "disconnected"
Symptoms: CheckESME returns persist: false, messages to this link fail.
Diagnostic steps:
-
Verify the SMSC is reachable from the proxy host:
telnet smsc.provider.com 2775 -
Check link configuration in
smpp_rules.toml:esme_addrandesme_port— correct SMSC address?esme_systemidandesme_password— correct credentials?esme_disabled— is the link accidentally disabled?
-
Check Enquire Link timeouts:
- If
esme_enquirelink_timeoutis too short, the proxy may disconnect from slow-responding SMSCs. Default is 40 seconds.
- If
-
Verify network/firewall rules — the proxy needs outbound TCP access to the SMSC on the configured port.
Resolution: The proxy automatically reconnects when the SMSC becomes available. No restart is needed. If credentials were changed, update smpp_rules.toml and restart the proxy container.
All links in a pool are down
Symptoms: Pool rate limit drops to zero, all messages to this pool are rejected.
Diagnostic steps:
- Check if the issue is on the SMSC side (all links connect to the same provider).
- Verify network connectivity to the SMSC endpoints.
- Check
/api/v1/dashboard/smpp-linksto see which specific links are affected.
Resolution: The pool will automatically recover as links reconnect. Monitor via dashboard for recovery.
Message Delivery Issues
Message not delivered (no DLR)
Diagnostic steps:
-
Check message status via API:
curl -X POST http://localhost:8080/api/v1/sms/info \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"esme": 100, "message_id": "msg-uuid"}' -
Review the
statusfield in the response:submitted— message was sent to SMSC, waiting for DLRDELIVERED— successfully delivered to the recipientUNDELIVERABLE— SMSC reported delivery failureEXPIRED— delivery timed out
-
If the message was never submitted, check SMPP link health and rate limits.
Message rejected by contact policy
When a message is rejected by the MCP, the API response will contain a status indicating the reason. Check the state field:
| State | Meaning | What to do |
|---|---|---|
ok | Message passed all policy checks | No issue — message was accepted |
daily_cp | Daily contact limit reached for this phone number | The recipient has already received the maximum number of messages today. Wait until the counter resets (midnight) |
weekly_cp | Weekly contact limit reached for this phone number | Same as above, but the weekly limit applies. Counter resets at the beginning of the week |
duplicate | Duplicate message detected | The same message to the same number was sent recently (within the dedup window). This is expected behavior |
blacklist | Phone number is in the blacklist | The recipient's number is in a blacklist file loaded from S3/MinIO. Remove the number from the blacklist CSV if this is incorrect |
unknown_strategy | Unknown MCP strategy requested | The strategy field in the request contains an unsupported value. Supported strategies: cp1, onbuild_cp1, cp2, blacklist |
High duplicate/blacklist rejection rate
If a large percentage of messages are being rejected:
- Duplicates — review whether the sending application is accidentally resending the same messages. Check the dedup time window in MCP settings.
- Blacklist — verify the blacklist CSV files in S3/MinIO are up to date. Check the auto-renewal schedule.
- Contact policy — review daily/weekly limits in MCP flows. They may be set too low for the intended traffic volume.
Authentication Errors
| Error Message | HTTP Status | Cause | Solution |
|---|---|---|---|
authorization header required | 401 | Missing Authorization header | Include Authorization: Bearer <token> in the request |
X-App-ID header required | 401 | Missing X-App-ID header | Include X-App-ID: <numeric_id> in the request |
invalid X-App-ID | 400 | X-App-ID is not a valid number | Ensure X-App-ID contains only digits |
unknown app_id | 401 | The specified app_id does not exist | Register a user first or use the correct app_id |
invalid or expired token | 401 | JWT token is expired or malformed | Login again to get a fresh token |
IP not allowed | 403 | Client IP is not in the esme_ip_whitelist | Add the client IP to the link's whitelist in smpp_rules.toml |
Rate Limiting Issues
Messages rejected with HTTP 429
The client is sending faster than the configured rate limit.
Diagnostic steps:
- Check current throughput:
curl http://localhost:8080/api/v1/dashboard/stats - Compare with configured limits in
smpp_rules.toml(esme_rateparameter) - Check if link health degradation has reduced the effective pool rate — see Link Health Monitoring
Resolution: Either reduce the client's sending rate or increase esme_rate / esme_rate_burst in the configuration (ensure the SMSC provider supports the higher rate).
Message Tracing
Every message processed by the proxy is assigned a UUID-based transaction ID that can be used to trace the message through the entire processing pipeline.
To trace a specific message:
- Note the
transaction_idfrom the send response. - Query the delivery status:
curl -X POST http://localhost:8080/api/v1/sms/info \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"esme": 100, "message_id": "msg-uuid"}' - The response includes: message status, per-segment delivery info, timestamps, routing information, and error details.
Useful Diagnostic Endpoints
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/healthy | GET | None | Service health check |
/metrics | GET | None | Prometheus metrics |
/dashboard/stats | GET | None | Real-time system statistics (RPS, counts) |
/dashboard/smpp-links | GET | None | Status of all SMPP connections |
/dashboard/load-balancers | GET | None | Pool statistics and traffic distribution |
/api/v1/sms/check-esme | POST | JWT | Check specific SMPP link status |
/api/v1/sms/info | POST | JWT | Query message delivery status |
/api/v1/settings/license | GET | JWT | Verify license status |
When to Contact Support
Escalate to the platform vendor if:
- The proxy fails to start or crashes repeatedly
- Messages are submitted successfully (status
submitted) but DLRs never arrive, and the SMSC provider confirms delivery - Rate limits appear incorrect despite correct
smpp_rules.tomlconfiguration - Redis or Aerospike connectivity issues persist after verifying network and Docker configuration
When contacting support, include: proxy version, Docker Compose configuration, smpp_rules.toml (with passwords redacted), output of /healthy, /dashboard/stats, and /dashboard/smpp-links.