Summary
The widget+cffi login strategy correctly detects the Garmin email MFA page and calls the configured prompt_mfa callback, but no OTP is delivered for that Widget SSO session.
OTP delivery works immediately when logging in through a normal web browser. However, an OTP generated by the browser session is rejected when entered into the python-garminconnect Widget MFA session, which appears to confirm that the OTP is session-specific.
Environment
garminconnect: 0.3.6
- Python: 3.12.13
- Runtime: Docker, based on
python:3.12-slim
- Docker host: Debian 13
- Garmin domain:
garmin.com
- Account MFA methods enabled:
Authentication code
from garminconnect import Garmin
api = Garmin(
email,
password,
prompt_mfa=lambda: input("Garmin MFA code: "),
)
api.login(tokenstore="/data/tokens")
I also reproduced the issue while explicitly skipping the rate-limited mobile strategies:
api.client.skip_strategies.update({
"mobile+cffi",
"mobile+requests",
})
This causes authentication to start directly with the Widget SSO strategy, but an OTP is still not delivered.
Steps to reproduce
- Use an account with email MFA enabled.
- SMS MFA was also enabled in the Garmin Account Security Center during troubleshooting.
- Call Garmin.login() with a prompt_mfa callback.
- The Widget SSO strategy reaches the MFA page.
- The callback prompts for a code:
- No new OTP is received by email or SMS.
- Log in through a normal web browser using the same account.
- The browser login OTP is delivered immediately.
- Entering that browser-generated OTP into the pending Widget MFA session fails with:
garminconnect.exceptions.GarminConnectAuthenticationError:
Widget MFA failed: GARMIN Authentication Application
Initial log with mobile strategies enabled
mobile+cffi returned 429: Mobile login returned 429 — IP rate limited by Garmin
mobile+requests returned 429: Mobile login returned 429 — IP rate limited by Garmin
Garmin MFA code:
The mobile 429 condition persisted for more than 32 hours.
The Widget strategy still reached the MFA prompt, so the mobile rate limit may be a separate issue.
Behavior after skipping mobile strategies
After setting:
api.client.skip_strategies.update({
"mobile+cffi",
"mobile+requests",
})
the Widget strategy was entered directly without the two mobile 429 responses, but no OTP was delivered.
Expected behavior
When the Widget SSO page is detected as email/SMS MFA, Garmin should deliver a new OTP associated with that Widget authentication session. Entering that OTP should complete authentication and allow the DI tokens to be persisted.
Actual behavior
The MFA page is detected and the callback is invoked, but no OTP is delivered for that session.
A code issued by a separate browser session is rejected by the Widget session.
Related issues / changes
Security / redaction
No email address, phone number, password, OTP, service ticket, Cookie, or OAuth token is included in this report.
Summary
The
widget+cffilogin strategy correctly detects the Garmin email MFA page and calls the configuredprompt_mfacallback, but no OTP is delivered for that Widget SSO session.OTP delivery works immediately when logging in through a normal web browser. However, an OTP generated by the browser session is rejected when entered into the
python-garminconnectWidget MFA session, which appears to confirm that the OTP is session-specific.Environment
garminconnect: 0.3.6python:3.12-slimgarmin.comAuthentication code
I also reproduced the issue while explicitly skipping the rate-limited mobile strategies:
This causes authentication to start directly with the Widget SSO strategy, but an OTP is still not delivered.
Steps to reproduce
Initial log with mobile strategies enabled
The mobile 429 condition persisted for more than 32 hours.
The Widget strategy still reached the MFA prompt, so the mobile rate limit may be a separate issue.
Behavior after skipping mobile strategies
After setting:
the Widget strategy was entered directly without the two mobile 429 responses, but no OTP was delivered.
Expected behavior
When the Widget SSO page is detected as email/SMS MFA, Garmin should deliver a new OTP associated with that Widget authentication session. Entering that OTP should complete authentication and allow the DI tokens to be persisted.
Actual behavior
The MFA page is detected and the callback is invoked, but no OTP is delivered for that session.
A code issued by a separate browser session is rejected by the Widget session.
Related issues / changes
The current behavior appears to occur after the detection added by fix: detect email-based MFA in widget SSO login #371: detection succeeds, but OTP delivery or completion for email-based MFA does not.
Security / redaction
No email address, phone number, password, OTP, service ticket, Cookie, or OAuth token is included in this report.