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

  1. Ensure the URL passed in is built with Scheme: "file" — verify with `u.Scheme == "file"` before calling URLToFilePath.
  2. 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.
  3. Use url.Parse on a string that already starts with "file://" rather than assembling the URL struct field-by-field.
  4. 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

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


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