Fix 'go: could not create module cache: mkdir /go/pkg/mod: permission denied' in Go

beginner๐Ÿ”ท Go2026-05-31| Go 1.16+ on Linux, macOS, Docker containers, CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins)

Error Message

go: could not create module cache: mkdir /go/pkg/mod: permission denied
#go#module cache#permission denied#go modules

The Error

go: could not create module cache: mkdir /go/pkg/mod: permission denied

Go can't write to its module cache directory. This usually surfaces when building inside Docker containers, running jobs in CI/CD pipelines, or after someone ran a go command with sudo โ€” which stamps the cache with root ownership and locks out your normal user.

Why This Happens

Go caches downloaded modules at $GOPATH/pkg/mod. Inside Docker images that's usually /go/pkg/mod; on a regular Linux or macOS machine it defaults to ~/go/pkg/mod.

The most common causes:

  • Docker image ran a previous step as root, creating /go/pkg/mod with root ownership before your app user runs go build.
  • Someone ran sudo go get or sudo go build on a shared machine, which seeded the cache as root.
  • GOPATH is set to a system directory (/go, /usr/local/go) that your current user can't write to.
  • CI/CD runner mounts a volume or cache that was created by a different user in a previous job.

Fix 1 โ€” Change Ownership of the Cache Directory (Most Common)

The cache got taken over by root. Take it back:

# Check who owns it
ls -la $(go env GOPATH)/pkg/mod

# Fix ownership (replace $USER with your username if needed)
sudo chown -R $USER:$USER $(go env GOPATH)/pkg/mod

Retry your go build or go mod download โ€” it should work immediately.

Fix 2 โ€” Point GOMODCACHE to a Writable Directory

On shared servers or restricted environments where you can't chown anything, redirect the cache to somewhere you already own:

# Temporary (current session only)
export GOMODCACHE=$HOME/go/pkg/mod

# Permanent โ€” add to ~/.bashrc or ~/.zshrc
echo 'export GOMODCACHE=$HOME/go/pkg/mod' >> ~/.bashrc
source ~/.bashrc

# Verify
go env GOMODCACHE

Run go mod download after setting this. Go will create the new cache path under your home directory and use it from then on.

Fix 3 โ€” Fix GOPATH (If Pointing to a System Directory)

Check what GOPATH currently resolves to:

go env GOPATH

Output like /go or /usr/local/go is the culprit โ€” those paths are owned by root. Reset to a user-owned location:

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

# Add to shell profile for persistence
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc

Fix 4 โ€” Docker Container Fix

Docker is where this error bites most often. A layer runs go commands as root, stamping /go/pkg/mod with root ownership. Then a later step switches to a non-root user โ€” and that user can't touch the cache.

Option A โ€” Run everything as the same user:

FROM golang:1.22

# All go commands run as root โ€” consistent, no permission mismatch
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o myapp .

Option B โ€” Create a non-root user and set GOPATH under their home:

FROM golang:1.22

RUN useradd -m -u 1001 appuser
USER appuser
WORKDIR /home/appuser/app

# GOPATH defaults to ~/go, which appuser owns
COPY --chown=appuser:appuser go.mod go.sum ./
RUN go mod download
COPY --chown=appuser:appuser . .
RUN go build -o myapp .

Option C โ€” Explicitly set GOMODCACHE to a writable path in Dockerfile:

ENV GOMODCACHE=/tmp/gomodcache
RUN go mod download

Fix 5 โ€” CI/CD Pipeline (GitHub Actions / GitLab CI)

Caching Go modules between pipeline runs speeds things up โ€” but a stale cache volume owned by the wrong user breaks everything. The safest approach: let the official setup action handle GOMODCACHE, and don't override GOPATH manually.

# GitHub Actions example
- name: Set up Go
  uses: actions/setup-go@v5
  with:
    go-version: '1.22'

# The setup-go action sets GOMODCACHE correctly โ€” don't override GOPATH manually
- name: Download modules
  run: go mod download

Running a self-hosted runner? A previous job may have left a root-owned cache behind. Clear it and start fresh:

sudo rm -rf ~/go/pkg/mod
go mod download

Verify the Fix

Run these after applying any fix above:

# Check cache directory exists and is accessible
ls -la $(go env GOMODCACHE)

# Try downloading modules fresh
go mod download

# Or just build your project
go build ./...

No permission errors and a clean build output means you're done.

Prevention Tips

  • Never use sudo go ... โ€” if a go command needs elevated access, something in your setup is wrong. Fix the underlying permission issue instead.
  • In Docker: decide on root vs. non-root early in your Dockerfile design and stay consistent throughout all layers that run go commands.
  • Set GOPATH explicitly in your shell profile rather than relying on the default, especially on servers where multiple users share the same Go installation.
  • Check directory permissions visually: if you're unsure whether your chmod and chown commands produce the right result, the Unix Permissions Calculator on ToolCraft lets you build and verify permission strings in the browser โ€” useful when you're dealing with multi-user Docker setups and want to double-check the numbers before applying them.

Related Error Notes