| Tested on | RHEL 10.2 with Go 1.27.0 |
|---|---|
| Package | go 1.27.0 |
| Applies to | Any host with Go 1.20+ installed |
| Privilege | Normal user |
| Scope | Import resolution for local packages, external modules, sibling modules with go.work or replace, and legacy GOPATH mode. Does not cover private module authentication, vendoring, or a full Go modules tutorial. |
| Related guides | Create a Go module go.mod file not found Import local package without GOPATH GOPATH vs GOROOT Golang tutorial |
go build, go test, and go install can stop with several related messages:
cannot find package "..."
package example/foo is not in std
no required module provides package example/foo
cannot find module providing package example/fooSetting GOPATH does not normally make an arbitrary directory importable when Go is operating in module mode. Start by checking which module or workspace Go selected and whether the import path matches that layout.
| Situation | First thing to check |
|---|---|
| Local package in same project | go.mod module path + package directory |
| External dependency | Import path + go get / go mod tidy |
| Another local module | go.work or local replace |
| GOPATH-era project | $GOPATH/src/<import-path> and active mode |
Standard package like fmt not found |
Go installation / GOROOT |
Check which module or workspace Go is using
Before you rename folders or export more environment variables, ask the Go command what context it selected from your current directory:
go env GOMOD GOWORK GOPATH GOROOT GO111MODULESample output from a normal module project (values vary by machine):
/tmp/go-demo-import/go.mod
/root/go
/usr/local/goGOMOD shows the go.mod file selected for the current directory. An empty value or /dev/null on Unix means Go did not find a module on the upward path—cd into the module tree or see go.mod file not found.
GOWORK shows an active workspace file when one applies. When GOWORK is empty, no workspace is active, so the current module context governs package resolution.
GOPATH supplies the default module-cache location unless GOMODCACHE is set, and the default binary-install location unless GOBIN is set. It also backs legacy GOPATH development mode. In module-aware builds it does not define your normal project import-path hierarchy.
GOROOT points at the Go installation and standard library. Do not change GOROOT manually as a routine import fix.
GO111MODULE is usually empty on current toolchains because module mode is the default. Legacy GOPATH development mode can still be selected explicitly when maintaining old projects, but it is not the recommended fix for a modern module layout.
Fix a local package in the same Go module
This is the most common case: code in the same repository, but the import string does not line up with go.mod and the directory tree.
Example layout:
demo/
├── go.mod
├── main.go
└── boo/
└── boo.gogo.mod:
module example.com/demo
go 1.21boo/boo.go:
package boo
import "fmt"
func Boo() {
fmt.Println("This is the Boo function")
}main.go:
package main
import (
"fmt"
"example.com/demo/boo"
)
func main() {
boo.Boo()
fmt.Println("This is the main call")
}For a package inside the same module, its import path is normally the module path from go.mod plus the package directory relative to the module root. Here that is example.com/demo/boo, not boo alone.
Package names conventionally match the final directory element, but what matters structurally is the import path and that every non-test .go file in one directory belongs to a single valid package. You cannot put package main in main.go and package boo in boo.go in the same directory and treat them as separate packages—give boo its own folder.
From the demo directory, run the module:
go run .Sample output:
This is the Boo function
This is the main callTypical local mistakes:
- Importing
booinstead ofexample.com/demo/boo - Leaving
boo.gobesidemain.gowhile the code still sayspackage boo - Using a module prefix in
importthat does not match themoduleline ingo.mod
go mod tidy synchronizes module requirements with imports in your source. It cannot repair a wrong local directory layout or a mismatched import prefix—fix the tree first, then tidy if external dependencies changed.
Fix "no required module provides package"
When the missing code is an external module, Go reports something like:
no required module provides package example.com/lib/foo; to add it:
go get example.com/lib/fooFirst confirm the import path is spelled correctly and matches how the dependency is published. A typo looks like a missing module.
When you genuinely need that package, add the requirement:
go get example.com/lib/fooOr run:
go mod tidywhen your source already imports the dependency and you want go.mod and go.sum synchronized. go mod tidy adds missing module requirements needed by packages in the module and removes unnecessary ones—it does not invent a local folder that was never on disk.
Use another local module with go.work or replace
Two modules on disk need an explicit link during development:
workspace/
├── app/
│ ├── go.mod
│ └── main.go
└── library/
├── go.mod
└── foo/
└── foo.goapp/go.mod might say module example.com/app and import example.com/library/foo. Without a workspace, go build in app/ fails because the library is not in the public module proxy.
The modern fix for active development is a workspace at a parent directory:
go work init ./app ./libraryBoth modules keep their own module paths. The workspace tells the Go command to use those local trees together. From app/, go build . and go run . then resolve example.com/library/foo from the sibling module.
Alternatively, in app/go.mod add both a requirement and a replace directive. A replace alone does not add the module to the dependency graph—the module must also be required:
require example.com/library v0.0.0
replace example.com/library => ../libraryAfter adding the local replace, run go mod tidy with the import present; it can add the matching require entry. You can also add the require line explicitly. You still need the replace to point at the local directory.
replace substitutes one module path with a local directory for that module. Use go.work when several modules change together; use replace when one consumer needs a local fork. Import the module path from go.mod, never a raw filesystem path in the import string.
Why "package X is not in std" appears
When Go sees:
import "foo/bar"and cannot resolve it from the selected module, workspace, or dependencies, some toolchains phrase the failure as:
package foo/bar is not in std (...)That does not automatically mean GOROOT is corrupted. The usual checks are:
- Is the import path spelled correctly?
- Does it include the full module prefix for local code?
- Are you inside the intended module or workspace?
- Is an external dependency actually required and downloadable?
Only investigate a damaged Go installation if even genuine standard packages such as fmt, net/http, or os cannot be found. For that situation, verify go env GOROOT and reinstall the toolchain if the standard library tree is missing.
Legacy GOPATH mode: when $GOPATH/src still matters
Module mode is the default and recommended workflow. Legacy GOPATH development mode still exists when explicitly selected and is what the slug on this page refers to.
In GOPATH development mode, an import:
import "example.com/me/project/foo"is expected under:
$GOPATH/src/example.com/me/project/fooExporting GOPATH=/some/path alone is insufficient if the source tree does not follow that layout. If you maintain an old GOPATH-only project, confirm the code lives under $GOPATH/src/<import-path> and that you are deliberately using GOPATH mode—not flipping GO111MODULE=off on a modern module tree as a shortcut.
For new work, initialize a module with go mod init and match import paths to the module line. See create a Go module for naming conventions.
Common package-resolution mistakes
| Symptom | Likely issue |
|---|---|
package X is not in std |
Import path does not resolve in selected module or workspace |
no required module provides package X |
External requirement missing or import path wrong |
| Local package cannot be imported | Module prefix or directory path is wrong |
| Works in one directory but not another | Different GOMOD / GOWORK selection |
| Setting GOPATH changes nothing | Build is using modules |
| Sibling module cannot be found | Add it to go.work or use replace |
Even fmt cannot be found |
Investigate Go installation / GOROOT |
| GOPATH project still fails | Check $GOPATH/src/<import-path> and active mode |
Summary
Go import errors look different on the surface, but they share one question: why could the toolchain not map your import line to a real package? Start with go env GOMOD and go env GOWORK so you know which module or workspace is active, then match local imports to the module path plus directory layout.
For code outside your module, add a real dependency with go get or synchronize requirements with go mod tidy after the import path is correct. For a sibling module on disk, wire it with go work or a replace directive instead of expecting GOPATH to bridge the gap.
Module mode is the default modern workflow. GOPATH still backs the module cache and installed tools, but it does not replace go.mod for normal projects. Treat legacy GOPATH layout as intentional maintenance of older trees, not the first fix when a module import fails.
References
- Go Modules Reference
- Go command documentation
- Tutorial: Get started with Go workspaces
- Go Wiki: GOPATH
- Go language specification — Packages

