larksuite/cli · error
official skills index redirected to non-HTTPS URL: %s
Error message
official skills index redirected to non-HTTPS URL: %s
What it means
FetchSkillsIndex fetches the official skills index over HTTP with a redirect check: the CheckRedirect hook rejects any redirect whose target URL is not HTTPS. This error is returned when the server (or a man-in-the-middle) redirects the request to a non-HTTPS URL, which the client treats as a security violation and aborts.
Source
Thrown at internal/selfupdate/updater.go:299
func (u *Updater) FetchSkillsIndex(source string) *NpmResult {
if u.SkillsIndexFetchOverride != nil {
return u.SkillsIndexFetchOverride()
}
r := &NpmResult{}
ctx, cancel := context.WithTimeout(context.Background(), skillsIndexFetchTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, skillsIndexURL(source), nil)
if err != nil {
r.Err = err
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 = errView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the index URL/source being fetched and use a canonical HTTPS skills-index URL
- If you control the redirect, fix the server/mirror to redirect only to https:// URLs
- Bypass local proxies/captive portals that rewrite redirects to http and retry
- Verify you are not pointing at a stale mirror; reconfigure the skills source to the official HTTPS index
Example fix
// before
res := updater.FetchSkillsIndex("http://internal-mirror.example.com/index.json")
// after
res := updater.FetchSkillsIndex("https://internal-mirror.example.com/index.json") Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(indexURL)
if err != nil || u.Scheme != "https" { /* fix the source URL before fetching */ } Type guard
func isHTTPS(s string) bool { u, err := url.Parse(s); return err == nil && u.Scheme == "https" } Try / catch
res := updater.FetchSkillsIndex(source)
if res.Err != nil {
if strings.Contains(res.Err.Error(), "redirected to non-HTTPS") {
// reconfigure source to an HTTPS index URL
} else {
return res.Err
}
} Prevention
- Always configure skills sources with https:// URLs
- Audit internal mirrors so redirects keep HTTPS
- Bypass proxies that rewrite redirects to plain http
- Treat any http redirect as a misconfiguration or attack signal, not something to allow
When it happens
Trigger: Calling Updater.FetchSkillsIndex(source) when the skills-index host responds with a 3xx redirect whose Location resolves to a URL with a scheme other than https (e.g. http://).
Common situations: Misconfigured internal mirror redirecting to plain HTTP; captive-portal or proxy rewriting redirects to http; typo'd or legacy index URL that redirects to a deprecated http endpoint; intentional downgrade attack (which this guard exists to block).
Related errors
- redirect from https to http is not allowed
- only https URLs are supported
- blocked redirect target: %w
- npm install timed out after %s
- pnpm install timed out after %s
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/b05ac92a88b4ee8e.
Report an issue: GitHub.