siyuan-note/siyuan · error

unexpected status code: %d

Error message

unexpected status code: %d

What it means

fetchBazaarIndexPath performs a GET of the bazaar index from the CDN with retries disabled and requires HTTP 200. Any other status code (403, 404, 5xx, etc.) yields this error containing the actual status. The response body is discarded, so the caller only learns the numeric status.

Source

Thrown at kernel/bazaar/index.go:191

		return
	}
	legacy, legacyErr := fetchBazaarIndexPath(ctx, bazaarLegacyIndexPath)
	if nil != legacyErr {
		return nil, fmt.Errorf("get current bazaar index failed: %w; get legacy bazaar index failed: %v", err, legacyErr)
	}
	return legacy, nil
}

func fetchBazaarIndexPath(ctx context.Context, indexPath string) (ret *bazaarIndexSnapshot, err error) {
	timeBucket := bazaarIndexNow().Unix() / int64(bazaarIndexCDNBucket/time.Second)
	u := fmt.Sprintf("%s%s?t=%d", bazaarIndexStatServer, indexPath, timeBucket)
	buf := &bytes.Buffer{}
	resp, err := httpclient.NewBrowserRequest().SetRetryCount(0).SetContext(ctx).SetOutput(buf).Get(u)
	if nil != err {
		return nil, err
	}
	if 200 != resp.StatusCode {
		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
	}
	return parseBazaarIndex(buf.Bytes())
}

func parseBazaarIndex(data []byte) (ret *bazaarIndexSnapshot, err error) {
	raw := map[string]json.RawMessage{}
	if err = json.Unmarshal(data, &raw); nil != err {
		return nil, err
	}
	if nil == raw {
		return nil, errors.New("invalid null bazaar index")
	}
	ret = &bazaarIndexSnapshot{
		packages:    map[string]*bazaarIndexPackage{},
		legacyStats: map[string]*bazaarStats{},
	}

	metaRaw, hasMeta := raw["meta"]

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Note the status code in the message: 429 → back off and retry later; 403/405 → check proxy/firewall and User-Agent handling; 404 → the index path is wrong or temporarily absent; 5xx → wait for the bazaar service to recover
  2. Retry after a delay — the time-bucketed cache-buster URL (t parameter) changes over time and the refresh loop will re-attempt
  3. Verify the index URL manually with curl to distinguish client network issues from server-side problems
  4. If the legacy path also fails, fetchBazaarIndex surfaces the combined error 251; fix whichever path reports the server-side cause
Defensive patterns

Strategy: retry

Validate before calling

// pre-check the endpoint reachable with expected status
resp, err := http.Head(indexURL)
// proceed only if err == nil && resp.StatusCode == 200

Try / catch

if err != nil {
    var statusErr interface{ Error() string }
    if strings.Contains(err.Error(), "unexpected status code: 429") {
        time.Sleep(backoff) // rate limited: retry later
    }
}

Prevention

When it happens

Trigger: A GET to <bazaarIndexStatServer><indexPath>?t=<timeBucket> returns a non-200 response: CDN rate limiting (429), auth/WAF blocking (403), removed index file (404), or origin server errors (500/502/503).

Common situations: CDN rate limiting after many requests; corporate proxy or firewall intercepting the request with a 403 page; bazaar index temporarily unpublished during a deploy; stale DNS pointing at a server without the index.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/0f5221055c1f03d6. Report an issue: GitHub.