Question
I am trying to run the following Go command on Ubuntu:
go get github.com/go-sql-driver/mysql
It fails with this error:
package github.com/go-sql-driver/mysql: cannot download, $GOPATH not set. For more details see: go help gopath
When I run go env, I get output similar to this:
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH=""
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread"
CGO_ENABLED="1"
Clearly, GOPATH is not set. How do I set the GOPATH environment variable on Ubuntu, and which file should I edit so the setting is available in my shell sessions?
Short Answer
By the end of this page, you will understand what GOPATH is, when it matters in Go, how to set it on Ubuntu, which shell startup file to edit, and how to verify that Go is using the value you configured.
Concept
GOPATH is an environment variable used by Go to define a workspace directory. Historically, Go stored downloaded packages, compiled files, and your own source code inside that workspace.
A common layout looked like this:
$GOPATH/
bin/
pkg/
src/
In older Go workflows, commands like go get expected GOPATH to be set so Go knew where to place downloaded code.
Why this matters
Environment variables let programs read configuration from the shell. Go checks variables such as:
GOROOT— where Go itself is installedGOPATH— your workspace locationPATH— which commands your shell can run directly
If GOPATH is empty in an older Go setup, tools like go get may fail because Go does not know where to download packages.
Important modern note
In modern Go versions, modules are the standard way to manage dependencies, and GOPATH is often less important than it used to be. However, if you are using an older Go installation, legacy instructions, or a system where the toolchain still expects it, setting GOPATH is still useful.
Typical Ubuntu approach
On Ubuntu, you usually set environment variables in a shell startup file such as:
~/.profile~/.bashrc~/.zshrcif you use Zsh
For a user-specific Go workspace, a common choice is:
export GOPATH="$HOME/go"
You often also add the Go bin directory to PATH:
export PATH="$PATH:$GOPATH/bin"
That allows commands installed by Go to be run directly from the terminal.
Mental Model
Think of GOPATH as Go's workshop folder.
GOROOTis the factory where Go itself was built and installed.GOPATHis your personal workbench.PATHis the list of drawers your shell searches when you type a command.
If Go needs to download tools or packages and does not know where your workbench is, it complains that GOPATH is not set.
On Ubuntu, editing a shell config file is like telling your terminal: "Every time you start, remember where my Go workspace lives."
Syntax and Examples
The basic Ubuntu setup looks like this:
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
Example: add it to ~/.profile
Open your profile file:
nano ~/.profile
Add these lines at the end:
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
Save the file, then reload it:
source ~/.profile
Verify the value:
go env GOPATH
Expected output:
/home/your-username/go
Why ~/.profile?
~/.profile is a common place for user environment variables on Ubuntu, especially for login shells. If your terminal is Bash and already loads ~/.bashrc, many developers put the same exports there instead.
Example: temporary setting for the current shell only
export GOPATH="$HOME/go"
This works immediately, but it disappears when you close the terminal. That is why editing a startup file is usually the better long-term solution.
Step by Step Execution
Consider this setup:
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
go env GOPATH
Here is what happens step by step:
-
export GOPATH="$HOME/go"- The shell creates an environment variable named
GOPATH. $HOMEexpands to your home directory, such as/home/alex.- So
GOPATHbecomes something like/home/alex/go.
- The shell creates an environment variable named
-
export PATH="$PATH:$GOPATH/bin"- The shell takes the existing
PATH. - It appends the
binfolder inside your Go workspace. - This allows executables installed there to be found when you type their names.
- The shell takes the existing
-
go env GOPATH- The Go tool reads the current environment.
- It prints the
GOPATHvalue it sees. - If the setup worked, it shows your configured directory.
Small trace example
If:
HOME=/home/sam- current
PATH=/usr/local/bin:/usr/bin
Then after these commands:
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
The values become:
GOPATH=/home/sam/go
PATH=/usr/local/bin:/usr/bin:/home/sam/go/bin
Now when you run:
go env GOPATH
Go prints:
/home/sam/go
Real World Use Cases
Setting environment variables like GOPATH is part of everyday development setup.
Common situations
-
Installing Go tools
- Some tools are installed into a Go workspace bin directory.
- Adding
$GOPATH/bintoPATHmakes those tools runnable.
-
Working with older Go projects
- Legacy codebases may expect a traditional
GOPATHworkspace layout.
- Legacy codebases may expect a traditional
-
Using cloud servers or fresh Ubuntu VMs
- Minimal systems often need manual environment setup.
-
Automating developer machines
- Setup scripts often define environment variables in shell config files.
-
CI or build environments
- Some pipelines explicitly set Go-related environment variables before running builds.
Example scenario
You log into a new Ubuntu server, install Go, and try to fetch a dependency. Without GOPATH, the command fails. After setting it in your shell profile and reloading, Go can use the workspace correctly.
Real Codebase Usage
In real projects, developers usually avoid hardcoding machine-specific paths inside application code. Instead, they configure the shell or build environment.
Common patterns
-
User-level configuration
- Set
GOPATHin~/.profile,~/.bashrc, or~/.zshrc.
- Set
-
Project documentation
- Teams document setup steps in a
READMEor onboarding guide.
- Teams document setup steps in a
-
Environment validation
- Setup scripts may check required tools with commands like:
go env GOPATH
which go
-
Early failure
- Build scripts often stop immediately if expected tools or variables are missing.
-
Tool installation workflow
- Developers commonly rely on
PATHincluding a Go bin directory so installed CLI tools can be used globally.
- Developers commonly rely on
Practical rule
Use shell configuration for machine setup, not Go source files. Environment variables belong in the environment, not in application logic.
Common Mistakes
1. Setting GOPATH only for the current terminal
This works:
export GOPATH="$HOME/go"
But only until you close the shell.
How to avoid it
Add the export line to a startup file like ~/.profile or ~/.bashrc.
2. Editing the wrong file
Not every shell reads the same file.
- Bash login shell: often
~/.profile - Bash interactive shell: often
~/.bashrc - Zsh:
~/.zshrc
How to avoid it
Check your shell:
echo $SHELL
Then edit the correct startup file.
3. Forgetting to reload the file
After editing a config file, the current shell does not automatically update.
Fix
Run:
source ~/.profile
or restart the terminal.
4. Confusing GOROOT and GOPATH
Broken idea:
export GOPATH="/usr/lib/go"
This points GOPATH at the Go installation itself, which is not what you want.
Better
export GOPATH="$HOME/go"
5. Forgetting to update PATH
If you install Go tools into $GOPATH/bin, they may not run directly unless that folder is in PATH.
Fix
export PATH="$PATH:$GOPATH/bin"
6. Using spaces around =
Broken shell syntax:
export GOPATH = "$HOME/go"
Correct syntax:
export GOPATH="$HOME/go"
Comparisons
| Concept | Purpose | Typical Value | Should you edit it? |
|---|---|---|---|
GOROOT | Location of the Go installation | /usr/lib/go or similar | Usually no |
GOPATH | Your Go workspace directory | $HOME/go | Yes, if needed |
PATH | Directories searched for commands | /usr/bin:/bin:... | Often yes |
~/.profile vs ~/.bashrc
| File | Common use | Good for GOPATH? |
|---|---|---|
~/.profile | Login shell environment setup | Yes |
~/.bashrc | Interactive Bash shell settings | Yes |
~/.zshrc | Interactive Zsh settings | Yes, if using Zsh |
Old Go workflow vs modern Go workflow
| Workflow | Dependency management | GOPATH importance |
|---|---|---|
| Older Go workspace model | Packages inside workspace | High |
| Modern Go modules | Dependencies managed per module | Lower |
If you are following older instructions or using an older Go version, GOPATH may still be required.
Cheat Sheet
# Check current Go environment
go env
# Check only GOPATH
go env GOPATH
# Temporary for current shell only
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
# Permanent for Bash login shells
nano ~/.profile
# Add:
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"
# Reload the file
source ~/.profile
Quick rules
- Use
GOPATHfor your workspace, not Go's installation directory. - A common value is
$HOME/go. - Add
$GOPATH/bintoPATHif you want Go-installed commands available globally. - Use
echo $SHELLto check which shell config file you should edit. - Restart the terminal or
sourcethe file after changes.
Common files
- Bash:
~/.profileor~/.bashrc - Zsh:
~/.zshrc
Verify setup
go env GOPATH
echo $GOPATH
FAQ
Which file should I edit to set GOPATH on Ubuntu?
Usually ~/.profile or ~/.bashrc for Bash. If you use Zsh, edit ~/.zshrc.
What is a good value for GOPATH?
A common choice is:
$HOME/go
Do I need to set GOROOT too?
Usually no. GOROOT is normally handled by the Go installation.
Why does go env show GOPATH as empty?
Because the environment variable has not been set in your current shell or config file.
Why did my GOPATH setting disappear after reopening the terminal?
You probably exported it only in the current session. Add it to a shell startup file for a persistent setting.
Should I add $GOPATH/bin to PATH?
Yes, if you want to run installed Go tools directly from the terminal.
Is GOPATH still used in modern Go?
Less than before. Modern Go mainly uses modules, but older setups and some tools may still rely on GOPATH.
Mini Project
Description
Set up a working Go workspace on Ubuntu so you can inspect your Go environment and make the configuration persist across terminal sessions. This mirrors the kind of setup developers do on a new machine or server.
Goal
Configure a persistent GOPATH and verify that Go recognizes it correctly.
Requirements
- Choose the correct shell startup file for your shell.
- Set
GOPATHto a directory inside your home folder. - Add the Go workspace bin directory to
PATH. - Reload the shell configuration.
- Verify the setup using
go env GOPATH.
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.