Daraja API · Troubleshooting
M-Pesa Daraja API Common Errors and Fixes (2026)
Reference guide to every M-Pesa Daraja API error code you're likely to hit, with root causes and how to fix them.
If you're integrating M-Pesa Daraja API into a Kenyan website or app, you'll hit errors. The official documentation lists error codes but rarely explains why you're getting them. This guide covers the most common Daraja API errors with real root causes and fixes — based on what actually happens in production, not just the docs.
STK Push ResultCode Reference
When you receive an STK Push callback, the ResultCode field tells you what happened. Code 0 means success. Anything else is a failure of some kind.
| Code | Meaning | What to Do |
|---|---|---|
| 0 | Success | Mark order paid, fulfill |
| 1 | Insufficient balance | Show user-friendly message, suggest top-up |
| 17 | Internal failure | Retry once, then show generic error |
| 26 | System busy | Backoff and retry after 30 seconds |
| 1001 | Unable to lock subscriber, transaction in progress | User has another M-Pesa transaction. Wait, retry. |
| 1019 | Transaction expired | User waited too long. Allow retry. |
| 1025 | An error occurred while sending push request | Network or Safaricom-side issue. Retry. |
| 1032 | Request cancelled by user | User pressed Cancel. Show retry button. |
| 1037 | DS timeout user cannot be reached | User didn't respond in 60s. Phone off or no signal. |
| 2001 | Wrong PIN | User entered wrong PIN. They can retry. |
Authentication Errors
"Invalid Access Token"
Token expired (1 hour TTL) or wasn't passed correctly in the Authorization header. Check: header format must be Bearer YOUR_TOKEN, not just the token. Cache tokens for ~50 minutes max.
"Invalid Authentication"
Consumer Key + Consumer Secret don't match a valid Daraja app, or you're using sandbox credentials against production endpoints (or vice versa). Check the environment URL.
"Invalid initiator information passed to processing API"
One of these:
- BusinessShortCode is wrong (typo, or sandbox shortcode used in production)
- PassKey was copied with leading/trailing whitespace
- Timestamp format wrong — must be YYYYMMDDHHMMSS without separators
- Password (base64 of ShortCode + PassKey + Timestamp) computed incorrectly
Phone Number Format Errors
Daraja expects phone numbers in international format with country code: 2547XXXXXXXX (12 digits total). Common mistakes:
+254712345678— remove the +0712345678— replace leading 0 with 254254 712 345 678— remove spaces254712345678— correct
Use a regex like ^254[17]\d{8}$ to validate before submitting.
Amount Format Errors
- Decimals: Daraja only accepts integers. KES 100.50 fails — round to 100 or 101.
- Zero or negative: Rejected. Validate amount > 0 server-side.
- Below minimum: Some Pay Bills have a minimum (often KES 10). Set a UI minimum to match.
- Above maximum: Default M-Pesa maximum is KES 250,000 per transaction. Above that you need special arrangements with Safaricom.
Callback Issues
"My callback never gets called"
Check in this order:
- Is your callback URL HTTPS? Daraja rejects HTTP. Use Let's Encrypt for free SSL.
- Is the URL publicly reachable? Test with
curl -X POST https://yourdomain.com/api/mpesa/callback - Is the URL whitelisted in Daraja portal settings?
- Does your server respond with HTTP 200 within 30 seconds?
- Did you get the response from the STK Push initiation? If
ResponseCode≠ 0 there, the request never reached the customer.
"Callback called multiple times"
Safaricom retries callbacks if your server doesn't respond 200, or sometimes even if it does (rare). Make your callback handler idempotent — check if the order is already marked paid before processing again. Use the MpesaReceiptNumber as the deduplication key.
"Go Live" Approval Issues
When applying for production access via "Go Live":
- Test cases must succeed in sandbox — Safaricom reviews your sandbox transaction history
- Production callback URL must be different from sandbox — both must be HTTPS
- Real Pay Bill or Till must be active — confirm with your Safaricom relationship manager
- Approval takes 1–3 business days — don't schedule launches expecting same-day
Production Performance Issues
STK prompts arrive slowly
Normal delivery is 5–10 seconds. If consistently slow (30+ seconds): check for Safaricom-side incidents at @safaricomltd. Also verify your server isn't adding latency before calling Daraja.
Some users never receive prompts
Likely causes: phone is off, low signal area, M-Pesa subscription issue (rare), Safari outage in their area. Always provide a Pay Bill fallback with clear instructions for users who can't complete STK.
Frequently Asked Questions
What does ResultCode 1032 mean in M-Pesa?+
ResultCode 1032 means "Request cancelled by user" — the customer received the STK Push prompt but pressed Cancel instead of entering their PIN. This is normal user behavior, not an error in your code. Show a friendly retry option.
What does ResultCode 1037 mean in M-Pesa?+
ResultCode 1037 means "DS timeout user cannot be reached" — the STK Push prompt was sent but the user didn't respond within 60 seconds. Could be: phone off, no network, or user simply didn't see the prompt. Allow them to retry.
Why am I getting "invalid initiator information" on Daraja?+
This usually means the BusinessShortCode + PassKey + Timestamp combination doesn't match what Safaricom expects. Most common cause: timestamp format wrong (must be YYYYMMDDHHMMSS, no separators) or PassKey copied with extra whitespace.
How do I handle Daraja API access token expiry?+
Access tokens expire after 1 hour. Cache the token in memory or Redis with a TTL of ~50 minutes (5-minute safety margin), then refresh. Avoid generating a new token for every request — Safaricom rate-limits token generation.
Why is my M-Pesa callback never received?+
Check: (1) callback URL is HTTPS (HTTP is rejected), (2) URL is publicly accessible (no localhost or behind firewalls), (3) URL is whitelisted in Daraja portal settings, (4) your server responds with HTTP 200 within 30 seconds.
For the full STK Push implementation guide, see our M-Pesa STK Push Tutorial. For callback URL specifics, see M-Pesa Callback URLs Setup.