The 30-Second Fix
The error occurs because the public Go Proxy (proxy.golang.org) cannot see your private code. To fix this, tell Go to bypass the proxy for your specific organization. Run this command in your terminal:
go env -w GOPRIVATE=github.com/your-org/*
Working with multiple internal domains? Separate them with commas. For example, if you use both GitHub and a self-hosted GitLab, use:
go env -w GOPRIVATE=github.com/your-org/*,gitlab.mycompany.com/*
Why does '410 Gone' happen?
Since the release of Go 1.13, the GOPROXY variable defaults to https://proxy.golang.org,direct. This means every time you run go get, your machine asks Google's public proxy for the code first.
When that proxy tries to fetch a private repository, it hits an authentication wall. Instead of returning a 403 Forbidden—which would confirm to the world that a private repo exists—the proxy returns 410 Gone. This security measure keeps your private project names hidden from the public. The proxy is effectively saying, "I don't know what this is, and I can't serve it to you."
The Go toolchain stops immediately when it receives this 410 status. It won't try a direct connection unless you explicitly tell it which paths are private.
Effective Solutions
1. Define Your Private Domains
Setting GOPRIVATE is the most reliable way to fix this. It acts as a bypass list for module paths. When a path matches this pattern, Go ignores the proxy and the public checksum database (SumDB) entirely.
For a specific repository:
export GOPRIVATE=github.com/username/my-project
For an entire company (Best Practice):
go env -w GOPRIVATE=github.com/acme-corp/*
2. Force Git to Use SSH
Even after fixing GOPRIVATE, your build might fail with a "terminal prompts disabled" error. This happens because Go tries to fetch modules via HTTPS, but your environment uses SSH keys for authentication. You can trick Git into swapping the protocol automatically:
git config --global url."git@github.com:your-org/".insteadOf "https://github.com/your-org/"
This command tells Git: "Whenever you see a request for https://github.com/your-org/, use git@github.com:your-org/ instead." Now, the Go tool can use your local ~/.ssh/id_rsa or ed25519 keys to log in.
3. Handling CI/CD and Docker
In automated environments like GitHub Actions or Jenkins, you cannot use go env -w because those environments are often ephemeral. Instead, pass these as standard environment variables in your pipeline script or Dockerfile.
Example Dockerfile snippet:
# Set Go to bypass proxy for internal modules
ENV GOPRIVATE=github.com/your-org/*
# Use a Personal Access Token (PAT) for private access
RUN git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/your-org/".insteadOf "https://github.com/your-org/"
Verifying the Fix
Confirm your settings are active by checking the environment:
go env GOPRIVATE
Next, try fetching the module with the verbose flag. This allows you to see exactly where Go is looking for the files:
go get -v github.com/your-org/private-repo@latest
If the configuration is correct, you will see Git cloning the repository directly from your source provider. You will no longer see references to proxy.golang.org for that specific module.
Common Mistakes
- Syntax Errors: Ensure there are no spaces around the
=sign.GOPRIVATE = github...will fail in most shells. - Checksum Failures: If you manually set
GONOPROXYbut forgetGONOSUMDB, your build will crash. The public checksum database cannot verify private code. UsingGOPRIVATEis better because it configures both settings at once. - Wildcard Scope: If your module is at
github.com/org/sub-folder/repo, the wildcardgithub.com/org/*will cover it. However,github.com/org(without the asterisk) might not.

