wtfutil/wtf · error

yfinance: unexpected status %d for symbol %q

Error message

yfinance: unexpected status %d for symbol %q

What it means

fetchChartMeta in the yfinance module fetches Yahoo Finance chart metadata for a symbol and requires HTTP 200. Any other status code (4xx rate limits/bad symbol routing, 5xx server errors, 429 throttling) aborts with this message carrying the numeric status and the requested symbol.

Source

Thrown at modules/stocks/yfinance/yquote.go:79

func fetchChartMeta(symbol string) (*chartMeta, error) {
	reqURL := chartAPIBaseURL + url.PathEscape(symbol) + "?range=1d&interval=1d"

	req, err := http.NewRequest(http.MethodGet, reqURL, nil)
	if err != nil {
		return nil, err
	}
	// Yahoo's unauthenticated endpoints are more reliable with a
	// browser-like User-Agent.
	req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; wtf-yfinance/1.0)")

	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("yfinance: unexpected status %d for symbol %q", resp.StatusCode, symbol)
	}

	var parsed chartResponse
	if err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {
		return nil, err
	}

	if parsed.Chart.Error != nil {
		return nil, fmt.Errorf("yfinance: API error for symbol %q: %v", symbol, parsed.Chart.Error)
	}

	if len(parsed.Chart.Result) == 0 {
		return nil, fmt.Errorf("yfinance: no results for symbol %q", symbol)
	}

	return &parsed.Chart.Result[0].Meta, nil
}

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Check the printed status: 429 means slow the widget's refresh interval or add a proxy for Yahoo requests
  2. Verify the symbol is valid by opening the Yahoo Finance chart URL for it in a browser
  3. Retry later for 5xx statuses — these are server-side
  4. Check corporate proxy/firewall interception of the request

Example fix

// before
meta, err := yfinance.FetchMeta("BRK") // 404 unknown symbol
// after
meta, err := yfinance.FetchMeta("BRK-B") // corrected symbol
Defensive patterns

Strategy: retry

Validate before calling

u := "https://query1.finance.yahoo.com/v8/finance/chart/" + url.PathEscape(symbol)
if symbol == "" || strings.ContainsAny(symbol, " ") { return errors.New("invalid symbol") }
_ = u

Type guard

func isRetryableStatus(code int) bool { return code == 429 || code >= 500 }

Try / catch

meta, err := fetchChartMeta(symbol)
if err != nil {
    var statusErr *statusError
    if errors.As(err, &statusErr) && statusErr.Code == 429 { backoffAndRetry(symbol) }
    else { log.Printf("yfinance %s: %v", symbol, err) }
}

Prevention

When it happens

Trigger: Any non-200 response from Yahoo's /v8/finance/chart/<symbol> endpoint: 404 for unknown/renamed symbols, 429 when rate-limited by Yahoo, 5xx when Yahoo is degraded, or a proxy/captive portal returning an HTML error page with a non-200 status.

Common situations: Yahoo rate-limiting frequent polling from one IP; delisted or renamed tickers configured in the widget; corporate proxies intercepting requests; Yahoo returning 999/403 to non-browser clients.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/86dc6003cc6678b6. Report an issue: GitHub.