we-promise/sure · error · Provider::YahooFinance::AuthenticationError
Failed to obtain Yahoo Finance crumb
Error message
Failed to obtain Yahoo Finance crumb
What it means
Raised when Yahoo Finance's getcrumb endpoint answers non-429 non-success (e.g. 401/403/5xx), or answers 200 with a crumb that fails valid_crumb? (blank or in INVALID_CRUMBS). The class is AuthenticationError for a bad/absent crumb but RateLimitError when the body literally says 'too many requests' - Yahoo signals throttling via the crumb text.
Source
Thrown at app/models/provider/yahoo_finance.rb:910
details: { status: cookie_response.status }
)
end
cookie = extract_cookie(cookie_response)
cookie_max_age = extract_cookie_max_age(cookie_response)
raise AuthenticationError, "Failed to obtain Yahoo Finance cookie" if cookie.blank?
crumb_response = authentication_client.get("#{base_url}/v1/test/getcrumb") do |req|
req.headers["Cookie"] = cookie
end
if crumb_response.status == 429
raise RateLimitError.new(
"Yahoo Finance rate limit exceeded",
details: { status: crumb_response.status }
)
end
unless crumb_response.success?
raise AuthenticationError.new(
"Failed to obtain Yahoo Finance crumb",
details: { status: crumb_response.status }
)
end
crumb = crumb_response.body.to_s.strip
unless valid_crumb?(crumb)
error_class = INVALID_CRUMBS.include?(crumb.downcase) ? RateLimitError : AuthenticationError
raise error_class.new(
"Failed to obtain Yahoo Finance crumb",
details: { status: crumb_response.status }
)
end
cache_duration = [ cookie_max_age || MAX_CRUMB_CACHE_DURATION, MAX_CRUMB_CACHE_DURATION ].min
[ cookie, crumb, cache_duration ]
end
View on GitHub (pinned to e69894adb9)
Solutions
- If the error is RateLimitError (body 'Too Many Requests'), back off for minutes and redo the whole cookie+crumb handshake
- If AuthenticationError: redo the handshake with a fresh cookie and verify extract_cookie pulled a real cookie (not blank)
- For EU regions, ensure the handshake satisfies Yahoo's consent flow or egress from a non-consent-walled region
- If a new junk crumb string appears consistently, add it to INVALID_CRUMBS and treat it as throttling
Example fix
# before
cookie, crumb = provider.send(:request_cookie_and_crumb, client)
# after - retry handshake once with fresh cookie, then give up gracefully
begin
cookie, crumb = provider.send(:request_cookie_and_crumb, client)
rescue Provider::YahooFinance::AuthenticationError => e
Rails.cache.delete("yahoo_finance_crumb_cache")
retry if (attempts += 1) == 1
raise
end Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
def yahoo_auth_failed?(err) err.is_a?(Provider::YahooFinance::AuthenticationError) end
Try / catch
attempts = 0 begin provider.fetch_quotes(symbols) rescue Provider::YahooFinance::AuthenticationError, Provider::YahooFinance::RateLimitError => e Rails.cache.delete(provider.class::HEALTH_STATUS_CACHE_KEY) retry if (attempts += 1) == 1 # one fresh handshake fall_back_to_alternate_provider(e) end
Prevention
- Retry the full handshake (cookie then crumb) once before failing - half-expired pairs are common
- Add newly observed junk-crumb strings to INVALID_CRUMBS so they classify as throttling
- For EU egress, verify the consent cookie flow works or route via a region that skips it
When it happens
Trigger: GET /v1/test/getcrumb returns 401/403/5xx (cookie rejected, consent not satisfied); crumb body is empty; crumb body is 'Too Many Requests' (mapped to RateLimitError via INVALID_CRUMBS).
Common situations: The fc.yahoo.com cookie missing required consent cookies (EU consent wall for EU egress IPs); Yahoo changing the crumb contract (new sentinel values not yet in INVALID_CRUMBS); cookie expired between the two requests; IP reputation issues making Yahoo hand out junk crumbs.
Related errors
- invalid_import_record
- Mercury provider is not configured
- Lunchflow provider is not configured
- Yahoo Finance authentication failed after crumb refresh
- Could not sign in with that passkey. Please try again or use
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/f260284dc56b7ad0.
Report an issue: GitHub.