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.

CodeMeaningWhat to Do
0SuccessConfirm with an STK Query, then mark order paid and fulfill
1Insufficient balanceShow user-friendly message, suggest top-up
17Internal failureRetry once, then show generic error
26System busyBackoff and retry after 30 seconds
1001Unable to lock subscriber, transaction in progressUser has another M-Pesa transaction. Wait, retry.
1019Transaction expiredUser waited too long. Allow retry.
1025An error occurred while sending push requestNetwork or Safaricom-side issue. Retry.
1032Request cancelled by userUser pressed Cancel. Show retry button.
1037DS timeout user cannot be reachedUser didn't respond before the prompt timed out (roughly 1–3 minutes). Phone off or no signal.
2001Wrong PINUser 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 254
  • 254 712 345 678 — remove spaces
  • 254712345678 — 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: The M-Pesa minimum is KES 1. Set a UI minimum to match.
  • Above maximum: The M-Pesa maximum is KES 250,000 per transaction, and a customer can send at most KES 500,000 a day. Split larger amounts or use another method.

Callback Issues

"My callback never gets called"

Check in this order:

  1. Is your callback URL HTTPS? Daraja rejects HTTP. Use Let's Encrypt for free SSL.
  2. Is the URL publicly reachable? Test with curl -X POST https://yourdomain.com/api/mpesa/callback
  3. Is the URL whitelisted in Daraja portal settings?
  4. Does your server respond with HTTP 200 quickly?
  5. 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":

  • You need an M-Pesa Org Portal administrator — the Go Live form asks for the username of a Business Administrator or Business Manager on the Org Portal (case-sensitive), and sends an OTP to that person's Safaricom line
  • The production passkey comes by email — Safaricom emails it to the developer after go-live; it is not the sandbox passkey
  • Real Pay Bill or Till must be active — confirm with your Safaricom relationship manager
  • Approval comes within 24 working hours (Monday to Friday, 8am to 5pm) — but setting up the Org Portal administrator first can take longer, so don't schedule launches expecting same-day

Production Performance Issues

STK prompts arrive slowly

Prompts normally arrive within seconds. If they are consistently slow: 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), Safaricom 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 before it timed out (roughly 1–3 minutes, depending on the phone). 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 quickly.

For the full STK Push implementation guide, see our M-Pesa STK Push Tutorial. For callback URL specifics, see M-Pesa Callback URLs Setup.