Introduction
The Go module proxy (proxy.golang.org) caches and serves public Go modules. When a private repository is requested through the proxy, it returns 410 Gone because the proxy cannot access private repositories. By default, GOPROXY is set to https://proxy.golang.org,direct, which falls back to direct access, but GONOSUMDB and GONOSUMCHECK must also be configured to skip checksum verification for private modules.
Symptoms
go mod download: github.com/myorg/private-lib@v1.2.3: reading https://proxy.golang.org/github.com/myorg/private-lib/@v/v1.2.3.mod: 410 Gonego: github.com/myorg/private-lib@v1.2.3: invalid version: git ls-remote -q origin in /tmp/gopath/pkg/mod/cache/vcs: exit status 128unrecognized import path "github.com/myorg/private-lib"- Works with direct git clone but fails with
go get
go: downloading github.com/myorg/private-lib v1.2.3
go: github.com/myorg/private-lib@v1.2.3: reading https://proxy.golang.org/github.com/myorg/private-lib/@v/v1.2.3.mod:
410 Gone
server response: not found: github.com/myorg/private-lib@v1.2.3: invalid version: git ls-remote -q https://github.com/myorg/private-lib in /tmp: exit status 128Common Causes
- Private repo not excluded from proxy
- Missing SSH key or token for git authentication
GOPRIVATEnot set or set incorrectly- CI environment lacks git credentials for private repos
- Corporate firewall blocking direct git access
Step-by-Step Fix
- 1.Configure GOPRIVATE for private modules:
- 2.```bash
- 3.# Skip proxy and checksum database for private repos
- 4.go env -w GOPRIVATE="github.com/myorg/*"
# For multiple organizations go env -w GOPRIVATE="github.com/myorg/*,gitlab.com/company/*,*.internal.example.com"
# Verify go env GOPRIVATE # Output: github.com/myorg/*,gitlab.com/company/*,*.internal.example.com ```
- 1.Configure git authentication for private repos:
- 2.```bash
- 3.# Using personal access token (GitHub)
- 4.git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"
# Using SSH git config --global url."git@github.com:".insteadOf "https://github.com/"
# Verify git can access the repo GIT_SSH_COMMAND="ssh -v" go mod download github.com/myorg/private-lib ```
- 1.Configure GOPROXY to bypass for private modules:
- 2.```bash
- 3.# Use proxy for public, direct for private (GOPRIVATE controls this)
- 4.go env -w GOPROXY="https://proxy.golang.org,direct"
# Or use a private proxy (e.g., Artifactory, Nexus) go env -w GOPROXY="https://artifactory.company.com/api/go/go-local,https://proxy.golang.org,direct" ```
- 1.Set environment in CI/CD pipeline:
- 2.```yaml
- 3.# GitHub Actions
- 4.- name: Configure Go for private repos
- 5.run: |
- 6.git config --global url."https://${{ secrets.GH_TOKEN }}@github.com/".insteadOf "https://github.com/"
- 7.go env -w GOPRIVATE="github.com/myorg/*"
- 8.go env -w GOPROXY="https://proxy.golang.org,direct"
# GitLab CI variables: GOPRIVATE: "gitlab.com/company/*" GOFLAGS: "-mod=readonly" before_script: - git config --global url."https://oauth2:${CI_JOB_TOKEN}@gitlab.com/".insteadOf "https://gitlab.com/" ```
- 1.Use .netrc for automated authentication:
- 2.```bash
- 3.# ~/.netrc
- 4.machine github.com login ${GITHUB_USERNAME} password ${GITHUB_TOKEN}
- 5.machine gitlab.com login oauth2 password ${GITLAB_TOKEN}
# Secure permissions chmod 600 ~/.netrc
# Go will use these credentials for module downloads go mod download ```
Prevention
- Set
GOPRIVATEin team onboarding documentation - Use
.netrcfor CI/CD authentication instead of git config rewriting - Pin dependency versions in
go.sumto avoid unexpected re-downloads - Use a private module proxy (Artifactory, Athens) for enterprise environments
- Add
GOPRIVATEcheck to CI validation scripts - Document private module authentication in project README