golang/go · error
local imports disallowed
Error message
local imports disallowed
What it means
Thrown by openPackage (src/cmd/compile/internal/noder/import.go) when the import path is a local name (starts with ./ or ../ or /, or is . or ..) and the compiler was invoked with -n / NoLocalImports. This flag forbids imports relative to the local file system, typically used when building the standard library or in constrained build environments.
Source
Thrown at src/cmd/compile/internal/noder/import.go:64
return pkg, err
}
func isDriveLetter(b byte) bool {
return 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z'
}
// is this path a local name? begins with ./ or ../ or /
func islocalname(name string) bool {
return strings.HasPrefix(name, "/") ||
runtime.GOOS == "windows" && len(name) >= 3 && isDriveLetter(name[0]) && name[1] == ':' && name[2] == '/' ||
strings.HasPrefix(name, "./") || name == "." ||
strings.HasPrefix(name, "../") || name == ".."
}
func openPackage(path string) (*os.File, error) {
if islocalname(path) {
if base.Flag.NoLocalImports {
return nil, errors.New("local imports disallowed")
}
if base.Flag.Cfg.PackageFile != nil {
return os.Open(base.Flag.Cfg.PackageFile[path])
}
// try .a before .o. important for building libraries:
// if there is an array.o in the array.a library,
// want to find all of array.a, not just array.o.
if file, err := os.Open(fmt.Sprintf("%s.a", path)); err == nil {
return file, nil
}
if file, err := os.Open(fmt.Sprintf("%s.o", path)); err == nil {
return file, nil
}
return nil, errors.New("file not found")
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Replace the local/relative import with the full canonical module import path.
- If you control the compiler invocation, do not pass -n (NoLocalImports) unless the build environment requires it.
- In module mode, ensure go.mod declares the module so you can use the full path.
Example fix
// before import "./util" // after import "example.com/myproject/util"
Defensive patterns
Strategy: validation
Validate before calling
// Flag relative imports in source before compiling with -n.
import "strings"
func isRelativeImport(p string) bool {
return strings.HasPrefix(p, "./") || strings.HasPrefix(p, "../") || p == "." || p == ".."
} Prevention
- Use canonical module import paths instead of relative ones.
- Only pass -n (NoLocalImports) when building stdlib/runtime where it is required.
- Lint for relative imports with goimports/golangci-lint in module projects.
When it happens
Trigger: A Go source file contains `import "./sub"` or `import "../sibling"`, the path is recognized as local by islocalname, and base.Flag.NoLocalImports is true (compiler flag -n).
Common situations: Building stdlib or runtime packages where the build system passes -n to enforce canonical import paths; using relative imports in a module-based project (relative imports are discouraged); a build tool that sets NoLocalImports by default.
Related errors
- file not found
- import path cannot be absolute path
- cannot import "main"
- import path is empty
- import path contains NUL
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/c63bab74f2864c35.
Report an issue: GitHub.