Date: 2026-02-06
Environment: Production (backend-v1.1.78)
4 recent 401 errors on the merchant code onboard endpoint, all from the same device/IP, caused by invalid Ed25519 request signature.
| Status | Count | Meaning |
|---|---|---|
| 201 | 20 | Success |
| 401 | 4 | Unauthorized (signature failure) |
| 409 | 4 | Conflict (user already a merchant) |
| 422 | 3 | Validation error (code state issues) |
Total: 31 requests, ~13% failure rate from auth
All 4 x 401s come from the same user/device:
- IP:
39.49.164.59 - Public Key:
OybhW257V5u6MD3C4tKjXLRShrA33hWVFaDaSsAzwII= - Merchant Code:
CvbVT2 - Time Window: 2026-02-05 17:18 – 17:43 UTC (4 attempts in 25 min)
- City/Country: Lahore, Pakistan
Accounts::VerifyRequestSignature::Service uncaught exception:
Accounts::VerifyRequestSignature::Support::Errors::InvalidSignatureError
- Invalid signature: signature was forged/corrupt
The signature verification service is called 3 times per request (retry logic in the auth pipeline) and fails each time. After all attempts fail, the authenticate_request before_action halts the chain and returns 401.
[17:43:32.796] [info] Calling VerifyRequestSignature::Service
public_key: OybhW257V5u6MD3C4tKjXLRShrA33hWVFaDaSsAzwII=
timestamp: 1770313412
method: POST
path: /api/v1/merchant_codes/CvbVT2/onboard
body: {"data[address]":"F7GR+G49 Shams mobile & nadra e sahulat...",
"data[store_photo]":"6569e030..."}
[17:43:32.796] [error] InvalidSignatureError - Invalid signature: signature was forged/corrupt
[17:43:32.801] [info] Calling VerifyRequestSignature::Service (retry 2) — same args
[17:43:32.804] [error] InvalidSignatureError - signature was forged/corrupt
[17:43:32.806] [info] Calling VerifyRequestSignature::Service (retry 3) — same args
[17:43:32.806] [error] InvalidSignatureError - signature was forged/corrupt
[17:43:32.805] [info] Filter chain halted as :authenticate_request rendered or redirected
[17:43:32.807] [info] Completed #onboard — 401 Unauthorized (16.7ms, 0 queries, user_id: null)
| Detail | 401 (Failed) | 201 (Succeeded) |
|---|---|---|
| Signature verification | InvalidSignatureError - forged/corrupt |
succeeded in 0.0s |
| User ID resolved | null (never authenticated) |
ae3854b0-c8bc-475d-9cd0-0cec63c001ab |
| DB queries | 0 (halted before controller action) | Multiple (S3 upload, service calls) |
| Public key | OybhW257V5u6... |
5s7xFTVjxBGXfB8JySQQ327oj7MEFT0rTqmS0S/m02o= |
| Body format | Same data[field] + store_photo hash |
Same data[field] + store_photo hash |
| Request duration | 16.7ms | 475ms |
-
Multipart body serialization mismatch — The signing payload shows
"data[store_photo]":"6569e030..."(a SHA hash of the file), while the actual request sends the file as multipart form data. If the client serializes the body for signing differently than the server reconstructs it for verification, the signature won't match. The&character in the address (Shams mobile & nadra e sahulat) could also be encoded differently between signing and verification. -
Keypair mismatch — The device may be signing with a different private key than the one corresponding to the public key
OybhW257V5u6...being sent in the header. -
Corrupted device keys — The device may need to re-register its keys (re-login / re-onboard device).
- Check if public key
OybhW257V5u6MD3C4tKjXLRShrA33hWVFaDaSsAzwII=is registered inaccounts_devicesoraccounts_embedded_walletstable - If not registered, the user needs to re-authenticate to register their device
- If registered, investigate the client-side signing logic for multipart requests — specifically how
store_photofile data is hashed and how special characters (&) in form fields are encoded during the signing step - Consider adding more detailed logging to the signature verification service to show the expected vs received signing payload for easier debugging