Question
I am trying to install doozer with this command:
goinstall github.com/ha/doozer
But I get errors like these:
goinstall: os: go/build: package could not be found locally
goinstall: fmt: go/build: package could not be found locally
goinstall: io: go/build: package could not be found locally
goinstall: reflect: go/build: package could not be found locally
goinstall: math: go/build: package could not be found locally
goinstall: rand: go/build: package could not be found locally
goinstall: url: go/build: package could not be found locally
goinstall: net: go/build: package could not be found locally
goinstall: sync: go/build: package could not be found locally
goinstall: runtime: go/build: package could not be found locally
goinstall: strings: go/build: package could not be found locally
goinstall: sort: go/build: package could not be found locally
goinstall: strconv: go/build: package could not be found locally
goinstall: bytes: go/build: package could not be found locally
goinstall: log: go/build: package could not be found locally
goinstall: encoding/binary: go/build: package could not be found locally
What should GOPATH and GOROOT be set to, and how are they supposed to work in Go?
Short Answer
By the end of this page, you will understand what GOROOT and GOPATH are, why Go needs them, how they differ, and how incorrect values can cause standard library packages like fmt or os to appear missing. You will also learn the modern context: when these variables matter, how to inspect them, and how to fix common setup problems.
Concept
GOROOT and GOPATH are environment variables used by Go to find code.
GOROOTpoints to the Go installation itself.GOPATHpoints to your workspace, where your own code and downloaded packages are stored.
What GOROOT means
GOROOT is the location where Go is installed. It contains:
- the Go compiler
- standard library source code
- standard library compiled packages
- Go toolchain binaries
If GOROOT is wrong, Go may fail to find built-in packages such as:
fmtosionet
That matches the kind of error shown in the question. If even standard packages cannot be found, the Go installation or GOROOT is likely incorrect.
What GOPATH means
GOPATH is a workspace directory for your own Go development. Historically, it was where Go expected to find:
- source code in
src/ - compiled packages in
pkg/ - installed binaries in
bin/
Example layout:
/home/user/go/
├── bin/
├── pkg/
└── src/
A package like github.com/ha/doozer would historically be placed under:
$GOPATH/src/github.com/ha/doozer
Why this matters
Go tools need to know:
- where the Go SDK lives (
GOROOT) - where your workspace lives (
GOPATH)
If those are mixed up, missing, or pointing to the wrong folders, commands like go, goinstall, or go install may fail.
Important modern note
Modern Go uses modules by default, so GOPATH is less central than it used to be. However:
GOROOTstill refers to the Go installationGOPATHstill exists and is used for things like the default binary install location- older commands like
goinstallbelong to older Go versions and older workspace behavior
So this question comes from the older GOPATH-based workflow, but the underlying concepts are still useful today.
Mental Model
Think of Go as having two homes:
GOROOTis Go's homeGOPATHis your workbench
GOROOT = the factory
This is where the language itself lives.
It contains the tools and built-in parts that ship with Go. If Go cannot find its own factory, it cannot even find basic parts like fmt or os.
GOPATH = your workshop
This is where you build your own things.
You keep your projects there, download dependencies there in older setups, and install tools there.
Simple analogy
Imagine a carpenter:
GOROOTis the tool factory that made the hammer and sawGOPATHis the carpenter's workshop where projects are built
If the factory address is wrong, you cannot even get a hammer. If the workshop address is wrong, your projects and downloaded materials go to the wrong place.
Syntax and Examples
In older Go setups, you might configure these environment variables like this.
Linux or macOS
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Windows
GOROOT=C:\Go
GOPATH=C:\Users\YourName\go
And add these to PATH:
C:\Go\bin
C:\Users\YourName\go\bin
Typical values
GOROOTis usually where Go was installed, such as/usr/local/goorC:\GoGOPATHis usually a directory you own, such as~/go
Check your setup
go env GOROOT
go env GOPATH
Example output:
/usr/local/go
/home/alex/go
Example: a healthy setup
go env GOROOT
# /usr/local/go
go env GOPATH
# /home/alex/go
In this setup:
- Go finds the standard library in
/usr/local/go - your own code can live under
/home/alex/go
Example: broken setup
export GOROOT=$HOME/go
This is wrong if $HOME/go is just your workspace. Go will look there for standard packages like fmt, fail to find them, and report errors similar to the ones in the question.
Modern note
In newer Go versions, you often do not need to set GOROOT manually at all. Go usually detects it automatically.
Step by Step Execution
Consider this setup:
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Now imagine you run:
go env GOROOT
go env GOPATH
Step by step
-
GOROOTis read as/usr/local/go- Go looks there for its own installation.
- It expects standard library code and build tools there.
-
GOPATHis read as/home/yourname/go- Go treats this as your workspace.
- In older workflows, downloaded packages go under
src/, compiled artifacts underpkg/, and binaries underbin/.
-
When you run a build command
- Go first needs its own standard packages.
- It looks in
GOROOTfor packages likefmtandos.
-
If
GOROOTis correctfmt,os,io, and other standard packages are found.- The command continues.
-
If
GOROOTis wrong- Go cannot find the standard library.
- You get many errors saying packages like
fmtoroscould not be found.
Trace example with a broken value
export GOROOT=$HOME/go
Suppose $HOME/go only contains your workspace folders:
/home/yourname/go/
├── bin/
├── pkg/
└── src/
Now Go looks there for standard library packages such as:
/home/yourname/go/src/fmt
/home/yourname/go/src/os
They are not there, because those belong to the Go installation, not your workspace. That causes the package lookup failures.
Key takeaway
If standard library packages are missing, suspect GOROOT or a broken Go installation before GOPATH.
Real World Use Cases
Even though Go modules changed the day-to-day workflow, these variables still matter in practice.
Diagnosing environment problems
If a developer machine or CI server cannot find Go packages, checking go env is one of the first debugging steps.
Installing command-line tools
Many Go-based tools install binaries into a location related to GOPATH, often:
$GOPATH/bin
This matters when a command installs successfully but cannot be run because its binary directory is not on PATH.
Working with older Go projects
Some legacy projects and setup guides still assume the GOPATH workspace model. Understanding it helps when maintaining older codebases.
CI/CD environments
Build servers may set custom Go paths. If those values are incorrect, builds can fail in ways that look confusing.
Multi-version Go setups
Developers using version managers or multiple Go installations sometimes accidentally point tools at the wrong GOROOT, causing mismatched builds or missing packages.
Real Codebase Usage
In real projects, developers usually rely on a few practical patterns.
1. Let Go manage GOROOT
In most modern environments, developers do not set GOROOT manually unless they have a special reason.
Why:
- manual configuration is easy to get wrong
- Go can usually detect its own install location
- incorrect
GOROOTcan break the standard library lookup
2. Use go env for debugging
A common debugging workflow is:
go env
This shows:
GOROOTGOPATH- module-related settings
- OS and architecture values
3. Keep GOPATH as a simple user-owned directory
Typical pattern:
/home/user/go
This avoids permission issues and keeps downloaded tools in one predictable place.
4. Add the binary directory to PATH
A common setup problem is:
- package installs successfully
- command is still not found
Developers fix that by adding the Go bin directory to PATH.
5. Prefer modern commands in current Go
In modern codebases, you usually use:
go install package@version
rather than the old goinstall command.
6. Use guard checks in setup scripts
Shell setup scripts often include checks like:
if ! command -v go >/dev/null 2>&1; then
echo "Go is not installed"
exit 1
fi
This is a guard clause pattern: fail early if the environment is not ready.
Common Mistakes
Here are the most common beginner mistakes with GOROOT and GOPATH.
Mistake 1: Setting GOROOT to the workspace directory
Broken example:
export GOROOT=$HOME/go
Why it breaks:
$HOME/gois usually your workspace- it is not the Go SDK installation
- Go cannot find standard packages there
Fix:
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
Or better: do not set GOROOT manually unless needed.
Mistake 2: Making GOPATH equal to GOROOT
Broken example:
export GOROOT=/usr/local/go
export GOPATH=/usr/local/go
Why it is a problem:
- it mixes the Go installation with your workspace
- it can create confusion and permission problems
Fix:
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
Mistake 3: Forgetting to add Go binaries to PATH
You may install a tool successfully but still get:
command not found
Fix:
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Mistake 4: Assuming every missing package error is a dependency issue
If missing packages include standard library names like:
fmtosio
then the problem is probably not the third-party package. It is more likely:
- bad
GOROOT - incomplete Go installation
- broken toolchain setup
Mistake 5: Following outdated commands without checking Go version
The command goinstall belongs to older Go workflows. In modern Go, use:
go install package@version
Mistake 6: Editing many environment variables before inspecting current values
Beginners often guess and change settings repeatedly.
Better approach:
go env GOROOT
go env GOPATH
which go
Inspect first, then change only what is wrong.
Comparisons
| Concept | Purpose | Typical Value | Common Mistake |
|---|---|---|---|
GOROOT | Location of the Go installation | /usr/local/go or C:\Go | Pointing it to your workspace |
GOPATH | Location of your workspace and installed tools | ~/go | Pointing it to the Go SDK |
PATH | Tells the shell where executables live | includes Go bin directories | Forgetting to include Go binaries |
GOROOT vs GOPATH
| Feature | GOROOT | GOPATH |
|---|---|---|
| Holds Go SDK | Yes | No |
| Holds your project workspace | No | Yes |
| Contains standard library | Yes | No |
| Usually set manually today | Rarely | Sometimes |
Wrong value breaks fmt/os lookup | Yes | Usually no |
Old Go workflow vs modern Go workflow
| Workflow | Dependency handling | Main install command | Role of GOPATH |
|---|---|---|---|
| Older GOPATH-based Go | packages stored in workspace | goinstall | central |
| Modern module-based Go | dependencies managed by go.mod | go install | less central |
When to suspect each variable
| Symptom | More likely cause |
|---|---|
fmt or os cannot be found | GOROOT or broken Go installation |
| installed command cannot be run | PATH missing Go bin directory |
| package placed in unexpected workspace location | GOPATH confusion |
Cheat Sheet
GOROOT = where Go itself is installed
GOPATH = where your workspace and installed tools live
PATH = where your shell looks for executables
Typical values
GOROOT=/usr/local/go
GOPATH=$HOME/go
PATH=$PATH:$GOROOT/bin:$GOPATH/bin
Useful commands
go env
go env GOROOT
go env GOPATH
which go
Key rules
- If standard packages like
fmtare missing, checkGOROOTfirst. GOPATHshould usually be a user-owned folder like~/go.- Do not set
GOPATHto the Go installation directory. - Do not set
GOROOTto your workspace directory. - In modern Go, you often do not need to set
GOROOTmanually.
Classic workspace layout
$GOPATH/
├── bin/
├── pkg/
└── src/
Fast diagnosis
go env GOROOT
go env GOPATH
If GOROOT points somewhere that does not contain the Go SDK, fix it.
Modern reminder
Use modern install commands when possible:
go install package@version
FAQ
What is the difference between GOROOT and GOPATH in Go?
GOROOT is the location of the Go installation. GOPATH is your workspace directory for projects and installed tools.
Do I need to set GOROOT manually?
Usually no. Modern Go installations normally detect GOROOT automatically.
What should GOPATH be set to?
A common choice is a directory you own, such as ~/go on Linux and macOS.
Why am I getting package could not be found locally for fmt or os?
Those are standard library packages. This usually means GOROOT is wrong or the Go installation is incomplete.
Can GOPATH and GOROOT be the same directory?
No. They serve different purposes and should not point to the same location.
Where do installed Go binaries go?
Commonly to GOPATH/bin, or another configured Go binary directory depending on your setup.
Is goinstall still the correct command?
No for modern Go. It is from older Go workflows. Today, go install is the standard command.
How can I check my current Go environment?
Run:
go env
Mini Project
Description
Create a small Go environment checker script that helps diagnose common setup problems. This project is useful because environment issues are one of the first obstacles beginners face when installing Go packages or tools.
Goal
Build a simple Go program that prints GOROOT, GOPATH, and warns when the setup looks suspicious.
Requirements
- Read the
GOROOTandGOPATHenvironment variables. - Print both values clearly.
- Warn if either value is empty.
- Warn if
GOROOTandGOPATHare the same. - Print a helpful message explaining what each variable is for.
Keep learning
Related questions
Are Go Maps Passed by Value or Reference?
Learn Go map parameter and return semantics: maps are passed by value, while copies share underlying data. Know when map pointers are useful.
Authentication for Go REST APIs: Sessions, Tokens, and Middleware
Learn practical authentication patterns for Go REST APIs, including password hashing, server sessions, bearer tokens, middleware, and security rules.
Automatic Build Versioning in Go: Embed Incrementing Build Numbers
Learn how to add automatic build versioning in Go using linker flags, build metadata, CI counters, and Git-based version values.