{"record":{"id":"772834b9c6295045","repo":"golang/go","slug":"invalid-file-proxy-url-with-non-path-elements","errorCode":null,"errorMessage":"invalid file:// proxy URL with non-path elements: %s","messagePattern":"invalid file:// proxy URL with non-path elements: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/modfetch/proxy.go","lineNumber":208,"sourceCode":"\n\tlistLatestOnce sync.Once\n\tlistLatest     *RevInfo\n\tlistLatestErr  error\n}\n\nfunc newProxyRepo(baseURL, path string) (Repo, error) {\n\t// Parse the base proxy URL.\n\tbase, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tredactedBase := base.Redacted()\n\tswitch base.Scheme {\n\tcase \"http\", \"https\":\n\t\t// ok\n\tcase \"file\":\n\t\tif *base != (url.URL{Scheme: base.Scheme, Path: base.Path, RawPath: base.RawPath}) {\n\t\t\treturn nil, fmt.Errorf(\"invalid file:// proxy URL with non-path elements: %s\", redactedBase)\n\t\t}\n\tcase \"\":\n\t\treturn nil, fmt.Errorf(\"invalid proxy URL missing scheme: %s\", redactedBase)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid proxy URL scheme (must be https, http, file): %s\", redactedBase)\n\t}\n\n\t// Append the module path to the URL.\n\turl := base\n\tenc, err := module.EscapePath(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\turl.Path = strings.TrimSuffix(base.Path, \"/\") + \"/\" + enc\n\turl.RawPath = strings.TrimSuffix(base.RawPath, \"/\") + \"/\" + pathEscape(enc)\n\n\treturn &proxyRepo{url, path, redactedBase, sync.Once{}, nil, nil}, nil\n}","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/modfetch/proxy.go#L190-L226","documentation":"newProxyRepo rejects a file:// proxy URL that carries anything beyond scheme+path+rawpath. A file URL must be purely local; a host segment, query, fragment, user info, or port makes it ambiguous/insecure and is refused.","triggerScenarios":"GOPROXY contains `file://host/path`, `file:///path?x=1`, or `file://user@host/path`. The comparison `*base != url.URL{Scheme,Path,RawPath}` fails.","commonSituations":"Confusing file:// (with host) and file:/// (path only); pasting an http URL and only changing the scheme; templating that injects a query string.","solutions":["Use the three-slash form pointing at a local directory: file:///var/cache/goproxy.","Remove any query, fragment, user, host, or port from the URL.","Ensure the path is absolute and the directory is readable by the go process."],"exampleFix":"// before\n//   GOPROXY=file://localhost/cache\n// after\n//   GOPROXY=file:///cache","handlingStrategy":"validation","validationCode":"func validateFileProxyURL(s string) error {\n    u, err := url.Parse(s)\n    if err != nil { return err }\n    if u.Scheme != \"file\" { return nil }\n    want := url.URL{Scheme: u.Scheme, Path: u.Path, RawPath: u.RawPath}\n    if *u != want { return fmt.Errorf(\"file:// proxy must be path-only: %s\", u.Redacted()) }\n    return nil\n}","typeGuard":"func isPlainFileURL(s string) bool {\n    u, err := url.Parse(s)\n    if err != nil { return false }\n    if u.Scheme != \"file\" { return false }\n    plain := url.URL{Scheme: u.Scheme, Path: u.Path, RawPath: u.RawPath}\n    return *u == plain\n}","tryCatchPattern":null,"preventionTips":["Use the three-slash file:///path form for local proxy caches.","Never paste an http URL and just change the scheme to file:."],"tags":["goproxy","file-scheme","config","url"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T11:17:21.771Z"}