golang/go · error
non-file URL
Error message
non-file URL
What it means
Thrown by urlToFilePath in cmd/go/internal/web when a *url.URL passed in does not use the "file" scheme. The web package converts between file:// URLs and OS file paths for the go command (module proxy caches, vendored downloads, -overlay file lists), and it will only ever reverse a file: URL into a local path — http, https, ftp, or any other scheme is rejected at the very first guard. The error is a hard precondition, not a recoverable state.
Source
Thrown at src/cmd/go/internal/web/url.go:21
// license that can be found in the LICENSE file.
package web
import (
"errors"
"net/url"
"path/filepath"
"strings"
)
// TODO(golang.org/issue/32456): If accepted, move these functions into the
// net/url package.
var errNotAbsolute = errors.New("path is not absolute")
func urlToFilePath(u *url.URL) (string, error) {
if u.Scheme != "file" {
return "", errors.New("non-file URL")
}
checkAbs := func(path string) (string, error) {
if !filepath.IsAbs(path) {
return "", errNotAbsolute
}
return path, nil
}
if u.Path == "" {
if u.Host != "" || u.Opaque == "" {
return "", errors.New("file URL missing path")
}
return checkAbs(filepath.FromSlash(u.Opaque))
}
path, err := convertFileURLPath(u.Host, u.Path)
if err != nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the URL passed in is built with Scheme: "file" — verify with `u.Scheme == "file"` before calling URLToFilePath.
- If you have an http(s) URL, download it to a local path first and then construct a file URL from the downloaded path via web.URLFromFilePath.
- Use url.Parse on a string that already starts with "file://" rather than assembling the URL struct field-by-field.
- Audit GOFLAGS, GOPROXY, and GOPATH/module-cache handling code for places that pass proxy URLs where the converter expects file URLs.
Example fix
// before
u, _ := url.Parse("https://proxy.golang.org/m.zip")
path, err := web.URLToFilePath(u) // -> "non-file URL"
// after
u, _ := url.Parse("file:///tmp/cache/m.zip")
path, err := web.URLToFilePath(u) Defensive patterns
Strategy: validation
Validate before calling
// before calling web.URLToFilePath:
if u.Scheme != "file" {
return fmt.Errorf("expected file URL, got %q", u.Scheme)
}
path, err := web.URLToFilePath(u) Type guard
func isFileURL(u *url.URL) bool { return u != nil && u.Scheme == "file" } Prevention
- Centralize file-URL construction in one helper that always sets Scheme to "file".
- Prefer web.URLFromFilePath(absPath) over hand-building url.URL structs.
- Never reuse the same URL variable for proxy URLs and file URLs.
When it happens
Trigger: Calling web.URLToFilePath (or any go-command code path that feeds it) with a url.URL whose Scheme is anything other than "file" — e.g. an http(s) module proxy URL, an ssh URL, or a relative URL whose Scheme was left empty. Constructed manually with &url.URL{Scheme: "https", ...} or parsed from "https://example.org/mod.zip" and handed to the converter.
Common situations: Plugins or scripts that wrap `go mod download`, `go get`, or GOPROXY/GOMODCACHE manipulation and reuse the same URL variable for both network fetches and local file lookups. Misconfigured GOFLAGS or -modcacherw tooling that records proxy URLs where file URLs were expected. A typo when building a file:// URL by hand (forgetting the Scheme or setting it to "https").
Related errors
- file URL missing path
- file URL encodes volume in host field: too few slashes?
- file URL missing drive letter
- file URL specifies non-local host
- path is not absolute
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/cf4c60621871af17.
Report an issue: GitHub.