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 Gone
  • go: github.com/myorg/private-lib@v1.2.3: invalid version: git ls-remote -q origin in /tmp/gopath/pkg/mod/cache/vcs: exit status 128
  • unrecognized import path "github.com/myorg/private-lib"
  • Works with direct git clone but fails with go get
bash
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 128

Common Causes

  • Private repo not excluded from proxy
  • Missing SSH key or token for git authentication
  • GOPRIVATE not set or set incorrectly
  • CI environment lacks git credentials for private repos
  • Corporate firewall blocking direct git access

Step-by-Step Fix

  1. 1.Configure GOPRIVATE for private modules:
  2. 2.```bash
  3. 3.# Skip proxy and checksum database for private repos
  4. 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. 1.Configure git authentication for private repos:
  2. 2.```bash
  3. 3.# Using personal access token (GitHub)
  4. 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. 1.Configure GOPROXY to bypass for private modules:
  2. 2.```bash
  3. 3.# Use proxy for public, direct for private (GOPRIVATE controls this)
  4. 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. 1.Set environment in CI/CD pipeline:
  2. 2.```yaml
  3. 3.# GitHub Actions
  4. 4.- name: Configure Go for private repos
  5. 5.run: |
  6. 6.git config --global url."https://${{ secrets.GH_TOKEN }}@github.com/".insteadOf "https://github.com/"
  7. 7.go env -w GOPRIVATE="github.com/myorg/*"
  8. 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. 1.Use .netrc for automated authentication:
  2. 2.```bash
  3. 3.# ~/.netrc
  4. 4.machine github.com login ${GITHUB_USERNAME} password ${GITHUB_TOKEN}
  5. 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 GOPRIVATE in team onboarding documentation
  • Use .netrc for CI/CD authentication instead of git config rewriting
  • Pin dependency versions in go.sum to avoid unexpected re-downloads
  • Use a private module proxy (Artifactory, Athens) for enterprise environments
  • Add GOPRIVATE check to CI validation scripts
  • Document private module authentication in project README