golang/go · error
invalid module version %q
Error message
invalid module version %q
What it means
Thrown by ParsePathVersion (list.go:342) when a module path@version argument has a version string (the part after '@') that begins with '-' or '/'. These prefixes are rejected because they can cause security problems when the version is interpolated into shell commands or filesystem paths (e.g., a version like '-rf' could be interpreted as a command flag). This is a security boundary, not merely a format check.
Source
Thrown at src/cmd/go/internal/modload/list.go:342
}
return &modinfo.ModuleError{Err: err.Error()}
}
// ParsePathVersion parses arg expecting arg to be path@version. If there is no
// '@' in arg, found is false, vers is "", and path is arg. This mirrors the
// typical usage of strings.Cut. ParsePathVersion is meant to be a general
// replacement for strings.Cut in module version parsing. If the version is
// invalid, an error is returned. The version is considered invalid if it is
// prefixed with '-' or '/', which can cause security problems when constructing
// commands to execute that use the version.
func ParsePathVersion(arg string) (path, vers string, found bool, err error) {
path, vers, found = strings.Cut(arg, "@")
if !found {
return arg, "", false, nil
}
if len(vers) > 0 && (vers[0] == '-' || vers[0] == '/') {
return "", "", false, fmt.Errorf("invalid module version %q", vers)
}
return path, vers, true, nil
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Sanitize or validate any user-supplied version string before appending it after '@' — reject versions starting with '-' or '/'.
- Use canonical semver version strings (e.g. 'v1.2.3') that never start with these characters.
- If building tooling on top of ParsePathVersion, wrap it and surface a clear validation error to the end user.
Example fix
// before
version := getUserInput() // e.g. "-rf"
arg := modulePath + "@" + version
path, vers, _, err := modload.ParsePathVersion(arg)
// after — validate first
if version != "" && (version[0] == '-' || version[0] == '/') {
return fmt.Errorf("invalid version: %q", version)
}
arg := modulePath + "@" + version Defensive patterns
Strategy: validation
Validate before calling
// Sanitize a user-supplied version before constructing path@version.
func sanitizeVersion(v string) error {
if v != "" && (v[0] == '-' || v[0] == '/') {
return fmt.Errorf("invalid module version %q: must not start with '-' or '/'", v)
}
return nil
} Prevention
- Never interpolate raw user input into a path@version string without sanitization.
- Prefer canonical semver versions (v1.2.3) which never start with '-' or '/'.
- When building CLI tools that accept version arguments, validate before passing to go commands.
When it happens
Trigger: Calling 'go get example.com/module@-foo' or 'go get example.com/module@/etc/passwd'. Any code path that calls ParsePathVersion with an arg containing '@' followed by a version starting with '-' or '/'. The function uses strings.Cut to split on '@', then inspects vers[0].
Common situations: User-supplied or script-generated module version strings that are not sanitized before being passed to go commands. Attempting to pass flags after '@' by mistake. Adversarial input in tooling that constructs module@version arguments.
Related errors
- leading hyphen
- crypto/dsa: invalid public key
- crypto/ecdh: private key and public key curves do not match
- crypto/ecdh: invalid private key
- crypto/ecdh: invalid public key
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c14e7c25c2b9ee85.
Report an issue: GitHub.