You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
eSignet-Thunder: Bug — Unknown UIN returns only a generic "Send OTP failed", and any subsequent action dead-ends the login page with "Invalid captcha" (ICS-1003) #2385
Entering a UIN that does not exist in the identity database returns a generic "Send OTP failed" banner. Nothing in the UI, in the /signin network response or in the pod logs indicates that the problem is an unknown / unavailable UIN, so the user has no way to know their ID is wrong. The service discards the underlying identity-system error code and replaces it with the catch-all send_otp_failed.
Worse, once the user is in the "Send OTP failed" state, any subsequent action — pressing the back arrow, or switching the Login ID option to Mobile Number / Email / NRC ID — flips the banner to "Invalid captcha" (ICS-1003, error.interceptor.captcha_invalid, "The captcha token could not be verified"), even though the captcha was solved and accepted on the previous attempt. From that point the screen is dead: the user can neither go back nor go forward. The only escape is the browser back button or closing the tab.
Steps to Reproduce
Part A — unhelpful error for an unknown UIN
Launch the OIDC login flow from the relying party and land on the eSignet login page.
Select Login ID Option -> UIN/VID.
Enter a UIN that is not present in the identity database — e.g. 5614716359.
Solve the "I'm not a robot" reCAPTCHA.
Click Get OTP.
Observe the banner, the /signin response in DevTools -> Network, and the eSignet pod logs.
Part B — dead-end "Invalid captcha" after the failure
Staying on the same screen after the "Send OTP failed" banner, do any of the following:
click the back arrow next to "Select a Login ID Option", or
click a different Login ID option (Mobile Number, Email, or NRC ID).
Observe the banner and the /signin response in DevTools -> Network.
Try to continue the flow, or to go back, using only the UI.
Actual Result
Part A
The banner reads only "Send OTP failed".
The /signin response and the pod logs carry the same generic failure — the identity-system error that actually explains the cause (UIN not available in the database) is not surfaced anywhere.
The user cannot tell whether the UIN is wrong, the OTP channel is unavailable, or the service is down.
Part B
The banner changes to "Invalid captcha" even though the captcha had just been solved and validated:
{
"flowStatus": "ERROR",
"data": {},
"error": {
"code": "ICS-1003",
"message": {
"key": "error.interceptor.captcha_invalid",
"defaultValue": "Invalid captcha"
},
"description": {
"key": "error.interceptor.captcha_invalid_description",
"defaultValue": "The captcha token could not be verified"
}
}
}
The captcha widget is not reset / re-armed, the back arrow does not navigate back, and the Login ID options do not switch — the user is stuck on this screen.
The only way out is the browser back button or closing the tab. There is no in-app recovery.
Expected Result
Part A
When the submitted UIN/VID is not present in the identity database, the UI should show a specific, user-actionable message (e.g. "The ID you entered was not found. Please check and try again.") rather than the catch-all "Send OTP failed".
The underlying identity-system error code should be preserved in the /signin error response and in the pod logs (error code only, no PII) so that the failure is diagnosable.
Part B
After any failed attempt the captcha widget should be reset and a fresh captcha token obtained before the next /signin call, so that a stale / already-consumed token is never resubmitted.
Navigating back, or switching the Login ID option, should always work and should clear the previous error — these actions must never produce a captcha error or leave the screen unusable.
The user must never be forced to use the browser back button or close the tab in order to recover from a failed OTP attempt.
Logs
/signin response for step 7 (captured from DevTools -> Network, see screenshot):
{"flowStatus":"ERROR","data":{},"error":{"code":"ICS-1003","message":{"key":"error.interceptor.captcha_invalid","defaultValue":"Invalid captcha"},"description":{"key":"error.interceptor.captcha_invalid_description","defaultValue":"The captcha token could not be verified"}}}
The pod logs for step 5 report only the generic send-OTP failure; the identity-system error code that would identify the unknown UIN is not present.
Screenshot/Screen Recording
"Send OTP failed" banner after submitting UIN 5614716359:
"Invalid captcha" banner after clicking the back arrow, with the ICS-1003 / "The captcha token could not be verified" response open in DevTools -> Network:
Attachments / Evidence / Links
Reproduced on: MOSIP ID identity system (healthservices-go-mosipid1.esqa.mosip.net), UIN used: 5614716359.
Not re-verified in this round on the Mock (healthservices-go.esqa.mosip.net) or Sunbird (healthservices-go-sunbird.esqa.mosip.net) identity systems. The generic-error mapping is shared code, so the same behaviour is expected on all three — please confirm during triage.
Code references (repo esignet-develop-go) for Part A — the identity-system error is swallowed and replaced by the catch-all:
esignet-service/internal/engine/mosip/authenticator.go:355 — sendOTPResult, err := p.callSendOtpEndpoint(...); if err != nil { return nil, shared.SendOTPFailedError }. callSendOtpEndpoint builds a descriptive error (fmt.Errorf("%s: %s", firstErr.ErrorCode, firstErr.ErrorMessage)) which is then discarded.
esignet-service/internal/engine/mock/authenticator.go:208 — identical pattern in the Mock provider.
esignet-service/internal/engine/shared/errors.go — SendOTPFailedError is a single catch-all with DefaultValue: "Send OTP failed"; there is no variant for "identity not found".
Short Summary of the Bug
Entering a UIN that does not exist in the identity database returns a generic "Send OTP failed" banner. Nothing in the UI, in the
/signinnetwork response or in the pod logs indicates that the problem is an unknown / unavailable UIN, so the user has no way to know their ID is wrong. The service discards the underlying identity-system error code and replaces it with the catch-allsend_otp_failed.Worse, once the user is in the "Send OTP failed" state, any subsequent action — pressing the back arrow, or switching the Login ID option to Mobile Number / Email / NRC ID — flips the banner to "Invalid captcha" (
ICS-1003,error.interceptor.captcha_invalid, "The captcha token could not be verified"), even though the captcha was solved and accepted on the previous attempt. From that point the screen is dead: the user can neither go back nor go forward. The only escape is the browser back button or closing the tab.Steps to Reproduce
Part A — unhelpful error for an unknown UIN
5614716359./signinresponse in DevTools -> Network, and the eSignet pod logs.Part B — dead-end "Invalid captcha" after the failure
/signinresponse in DevTools -> Network.Actual Result
Part A
/signinresponse and the pod logs carry the same generic failure — the identity-system error that actually explains the cause (UIN not available in the database) is not surfaced anywhere.Part B
{ "flowStatus": "ERROR", "data": {}, "error": { "code": "ICS-1003", "message": { "key": "error.interceptor.captcha_invalid", "defaultValue": "Invalid captcha" }, "description": { "key": "error.interceptor.captcha_invalid_description", "defaultValue": "The captcha token could not be verified" } } }Expected Result
Part A
/signinerror response and in the pod logs (error code only, no PII) so that the failure is diagnosable.Part B
/signincall, so that a stale / already-consumed token is never resubmitted.Logs
/signinresponse for step 7 (captured from DevTools -> Network, see screenshot):{"flowStatus":"ERROR","data":{},"error":{"code":"ICS-1003","message":{"key":"error.interceptor.captcha_invalid","defaultValue":"Invalid captcha"},"description":{"key":"error.interceptor.captcha_invalid_description","defaultValue":"The captcha token could not be verified"}}}The pod logs for step 5 report only the generic send-OTP failure; the identity-system error code that would identify the unknown UIN is not present.
Screenshot/Screen Recording
"Send OTP failed" banner after submitting UIN
5614716359:"Invalid captcha" banner after clicking the back arrow, with the
ICS-1003/ "The captcha token could not be verified" response open in DevTools -> Network:Attachments / Evidence / Links
healthservices-go-mosipid1.esqa.mosip.net), UIN used:5614716359.healthservices-go.esqa.mosip.net) or Sunbird (healthservices-go-sunbird.esqa.mosip.net) identity systems. The generic-error mapping is shared code, so the same behaviour is expected on all three — please confirm during triage.esignet-develop-go) for Part A — the identity-system error is swallowed and replaced by the catch-all:esignet-service/internal/engine/mosip/authenticator.go:355—sendOTPResult, err := p.callSendOtpEndpoint(...); if err != nil { return nil, shared.SendOTPFailedError }.callSendOtpEndpointbuilds a descriptive error (fmt.Errorf("%s: %s", firstErr.ErrorCode, firstErr.ErrorMessage)) which is then discarded.esignet-service/internal/engine/mock/authenticator.go:208— identical pattern in the Mock provider.esignet-service/internal/engine/shared/errors.go—SendOTPFailedErroris a single catch-all withDefaultValue: "Send OTP failed"; there is no variant for "identity not found".5614716359on a different environment, but a different failure point (OTP submission returning "Sign-in form is not available at the moment"). Not a duplicate of this report.