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

  1. Fetch the URL manually (curl 'https://<importPath>?go-get=1') and confirm it is well-formed HTML containing the go-import meta tag
  2. Ensure the server returns Content-Type: text/html; charset=utf-8
  3. Check the server isn't returning a login/redirect HTML page or a WAF challenge
  4. 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

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


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/443108ac55cfd19a. Report an issue: GitHub.