golang/go · error
insecure URL: %s
Error message
insecure URL: %s
What it means
Thrown by cmd/go/internal/web.get when a URL with scheme 'http' is fetched in SecureOnly security mode. SecureOnly is the default mode for module fetching: it rejects plain HTTP to prevent credential and code injection over unencrypted links. The error is returned (not printed) so callers can wrap it with request context.
Source
Thrown at src/cmd/go/internal/web/http.go:223
if cfg.BuildX {
fmt.Fprintf(os.Stderr, "# get %s: %v\n", secure.Redacted(), err)
}
if security != Insecure || url.Scheme == "https" {
// HTTPS failed, and we can't fall back to plain HTTP.
// Report the error from the HTTPS attempt.
return nil, err
}
}
}
if res == nil {
switch url.Scheme {
case "http":
if security == SecureOnly {
if cfg.BuildX {
fmt.Fprintf(os.Stderr, "# get %s: insecure\n", url.Redacted())
}
return nil, fmt.Errorf("insecure URL: %s", url.Redacted())
}
case "":
if security != Insecure {
panic("should have returned after HTTPS failure")
}
default:
if cfg.BuildX {
fmt.Fprintf(os.Stderr, "# get %s: unsupported\n", url.Redacted())
}
return nil, fmt.Errorf("unsupported scheme: %s", url.Redacted())
}
insecure := new(urlpkg.URL)
*insecure = *url
insecure.Scheme = "http"
if insecure.User != nil && security != Insecure {
if cfg.BuildX {
fmt.Fprintf(os.Stderr, "# get %s: insecure credentials\n", insecure.Redacted())View on GitHub (pinned to b6b368adc5)
Solutions
- Set GOINSECURE=<host>[,<host>...] env var so the host is fetched in Insecure mode (allows HTTP fallback and skips TLS verify).
- Switch the module/replace URL to https:// — the preferred fix.
- Route through an HTTPS-speaking GOPROXY (e.g. Athens, Athens-like proxy) that then talks HTTP upstream.
- For vanity imports, fix the go-import meta tag on the server to advertise https.
Example fix
// before: go.mod replace example.com/m => http://internal.corp/m // after (option A — HTTPS) replace example.com/m => https://internal.corp/m // after (option B — allow HTTP for that host) // $ GOINSECURE=internal.corp go build
Defensive patterns
Strategy: validation
Validate before calling
// Validate URL scheme and security policy before fetching.
func isFetchAllowed(u *urlpkg.URL, allowInsecure map[string]bool) error {
switch u.Scheme {
case "https", "":
return nil
case "http":
if !allowInsecure[u.Hostname()] {
return fmt.Errorf("refusing plain-HTTP fetch for %s without GOINSECURE opt-in", u)
}
return nil
default:
return fmt.Errorf("unsupported scheme %q", u.Scheme)
}
} Prevention
- Default to https:// in every go.mod replace directive and vanity import.
- Maintain a documented list of hosts requiring GOINSECURE and audit it regularly.
- In CI, fail the build if a module resolves to plain HTTP unexpectedly (grep go.sum / go env).
- Prefer a corporate HTTPS proxy over allowing plain HTTP per-host.
When it happens
Trigger: Calling web.get/web.Get/web.GetBytes/web.GetMaybe with a URL whose Scheme=="http" while security==SecureOnly (the zero value). Happens when a go.mod has a plain-HTTP replace directive or a vanity import resolves to http:// without the host being listed in GOINSECURE.
Common situations: A private module server reachable only over HTTP inside a corp network; a git-over-HTTP vanity URL; CI environments where TLS termination is unavailable. The user forgot to set GOINSECURE=<host> or GOPROXY=https://...
Related errors
- refusing to pass credentials to insecure URL: %s
- tls: invalid server key share
- tls: invalid signature by the server certificate: {err}
- tls: invalid server finished hash
- https fetch: %v
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/97a6b0c42b99b438.
Report an issue: GitHub.