golang/go · error
parsing %s: %v
Error message
parsing %s: %v
What it means
Emitted by repoRootForImportDynamic when parseMetaGoImports fails to tokenize the fetched HTML body for <meta name="go-import"> tags and produced zero candidate imports. The %s is the import path; %v is the HTML parse error. Distinct from a missing-tags error (1150): this is a parser failure.
Source
Thrown at src/cmd/go/internal/vcs/vcs.go:1015
if err != nil {
msg := "https fetch: %v"
if security == web.Insecure {
msg = "http/" + msg
}
return nil, fmt.Errorf(msg, err)
}
body := resp.Body
defer body.Close()
imports, err := parseMetaGoImports(body, mod)
if len(imports) == 0 {
if respErr := resp.Err(); respErr != nil {
// If the server's status was not OK, prefer to report that instead of
// an XML parse error.
return nil, respErr
}
}
if err != nil {
return nil, fmt.Errorf("parsing %s: %v", importPath, err)
}
// Find the matched meta import.
mmi, err := matchGoImport(imports, importPath)
if err != nil {
if _, ok := err.(ImportMismatchError); !ok {
return nil, fmt.Errorf("parse %s: %v", url, err)
}
return nil, fmt.Errorf("parse %s: no go-import meta tags (%s)", resp.URL, err)
}
if cfg.BuildV {
log.Printf("get %q: found meta tag %#v at %s", importPath, mmi, url)
}
// If the import was "uni.edu/bob/project", which said the
// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
// make sure we don't trust Bob and check out evilroot.com to
// "uni.edu" yet (possibly overwriting/preempting another
// non-evil student). Instead, first verify the root and see
// if it matches Bob's claim.View on GitHub (pinned to b6b368adc5)
Solutions
- Fetch the URL manually (curl 'https://<importPath>?go-get=1') and confirm it is well-formed HTML containing the go-import meta tag
- Ensure the server returns Content-Type: text/html; charset=utf-8
- Check the server isn't returning a login/redirect HTML page or a WAF challenge
- Validate the body passes an HTML parser (e.g. x/net/html)
Defensive patterns
Strategy: validation
Validate before calling
// Validate the vanity page parses and contains a go-import meta tag
import (
"io"
"net/http"
"strings"
"golang.org/x/net/html"
)
func hasGoImport(u string) (bool, error) {
r, err := http.Get(u + "?go-get=1")
if err != nil { return false, err }
defer r.Body.Close()
doc, err := html.Parse(r.Body)
if err != nil { return false, err }
var walk func(*html.Node) bool
walk = func(n *html.Node) bool {
if n.Type == html.ElementNode && n.Data == "meta" {
for _, a := range n.Attr { if a.Key == "name" && a.Val == "go-import" { return true } }
}
for c := n.FirstChild; c != nil; c = c.NextSibling { if walk(c) { return true } }
return false
}
_ = io.EOF
return walk(doc), nil
} Prevention
- Smoke-test vanity pages with curl '?go-get=1' after every server change
- Return Content-Type: text/html and valid UTF-8 from the vanity endpoint
- Don't put JSON or login HTML at the go-get endpoint
When it happens
Trigger: The server returns HTTP 200 with malformed HTML or a body the meta-tag parser cannot tokenize (unclosed tags, invalid encoding, non-UTF-8 bytes). The resp.Err() check is skipped because zero imports were produced.
Common situations: Vanity server returning an HTML error/login page in the body with status 200; CDN injecting script that breaks the tokenizer; server returning JSON or binary instead of text/html; charset mislabeling.
Related errors
- ReadZip: encoded file exceeds allowed size
- https fetch: %v
- parse %s: %v
- parse %s: no go-import meta tags (%s)
- %s and %s disagree about go-import for %s
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/443108ac55cfd19a.
Report an issue: GitHub.