larksuite/cli · error
official skills index returned HTTP %d
Error message
official skills index returned HTTP %d
What it means
FetchSkillsIndex recorded on its result that the official skills index endpoint answered with a status outside 2xx; non-HTTPS redirects were already rejected earlier by the CheckRedirect hook, so this is a server-side index availability failure.
Source
Thrown at internal/selfupdate/updater.go:311
return r
}
client := transport.NewHTTPClient(0)
client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
if req.URL.Scheme != "https" {
return fmt.Errorf("official skills index redirected to non-HTTPS URL: %s", req.URL.Redacted())
}
return nil
}
resp, err := client.Do(req)
if err != nil {
r.Err = err
return r
}
defer resp.Body.Close()
if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
r.Err = fmt.Errorf("official skills index returned HTTP %d", resp.StatusCode)
return r
}
limited := io.LimitReader(resp.Body, skillsIndexMaxBodySize+1)
if _, err := io.Copy(&r.Stdout, limited); err != nil {
r.Err = err
return r
}
if r.Stdout.Len() > skillsIndexMaxBodySize {
r.Stdout.Reset()
r.Err = fmt.Errorf("official skills index exceeds %d bytes", skillsIndexMaxBodySize)
return r
}
return r
}
func (u *Updater) ListGlobalSkills() *NpmResult {
return u.runSkillsListGlobal()View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Read the HTTP status in the message: for 404 verify the skills-index URL/source is current, for 403/401 check access/auth to the mirror
- For 429 wait and retry later (respect rate limits) or reduce polling frequency
- For 5xx check the service status of the index host and retry after the outage
- Check proxy/VPN configuration that may be intercepting requests to the index host
Example fix
// before
res := updater.FetchSkillsIndex(source)
if res.Err != nil { log.Fatal(res.Err) }
// after
res := updater.FetchSkillsIndex(source)
if res.Err != nil {
var statusMsg string
if _, err := fmt.Sscanf(res.Err.Error(), "official skills index returned HTTP %s", &statusMsg); err == nil && strings.HasPrefix(statusMsg, "5") {
log.Printf("index host error, retrying later: %v", res.Err)
} else {
log.Fatal(res.Err)
}
} Defensive patterns
Strategy: retry
Validate before calling
resp, err := http.Head(indexURL)
if err == nil && (resp.StatusCode < 200 || resp.StatusCode >= 300) { /* endpoint unhealthy; fix URL/auth before FetchSkillsIndex */ } Try / catch
res := updater.FetchSkillsIndex(source)
if res.Err != nil {
if strings.Contains(res.Err.Error(), "returned HTTP 5") || strings.Contains(res.Err.Error(), "HTTP 429") {
// transient: retry with backoff
} else {
return res.Err // 404/403: fix URL or access
}
} Prevention
- Pin to the current, documented skills-index URL
- Check auth requirements on internal mirrors before fetching
- Back off on 429 instead of hammering the endpoint
- Monitor index host status for 5xx outages
When it happens
Trigger: Calling Updater.FetchSkillsIndex(source) when the skills-index endpoint responds with a non-2xx status — 404 for a bad/removed index path, 403 for blocked access, 429 rate limiting, or 5xx server errors.
Common situations: Index URL changed or versioned path removed (404); auth required by an internal mirror (401/403); rate limiting by the CDN (429); upstream outage (500/502/503); proxy returning an error page.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- app registration failed: HTTP %d – response not JSON
- Device authorization failed: read body: %v
- failed to read response body in security transport: %w
- response parse error: %w (body: %s)
- failed to read TAT response: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/f6cf2f6fd80f56f2.
Report an issue: GitHub.