Cách khắc phục nhanh trong 30 giây
Lỗi này xảy ra do Go Proxy công khai (proxy.golang.org) không thể truy cập mã nguồn riêng tư của bạn. Để khắc phục, hãy yêu cầu Go bỏ qua proxy đối với tổ chức (organization) cụ thể của bạn. Chạy lệnh sau trong terminal:
go env -w GOPRIVATE=github.com/your-org/*
Bạn làm việc với nhiều domain nội bộ? Hãy phân tách chúng bằng dấu phẩy. Ví dụ, nếu bạn sử dụng cả GitHub và một GitLab tự host, hãy dùng:
go env -w GOPRIVATE=github.com/your-org/*,gitlab.mycompany.com/*
Tại sao lỗi '410 Gone' xảy ra?
Kể từ phiên bản Go 1.13, biến GOPROXY mặc định là https://proxy.golang.org,direct. Điều này có nghĩa là mỗi khi bạn chạy go get, máy tính của bạn sẽ hỏi proxy công khai của Google để lấy mã nguồn trước.
Khi proxy đó cố gắng lấy một kho lưu trữ riêng tư, nó sẽ gặp rào cản xác thực. Thay vì trả về lỗi 403 Forbidden—điều này sẽ xác nhận với thế giới rằng kho lưu trữ riêng tư đó tồn tại—proxy sẽ trả về 410 Gone. Biện pháp bảo mật này giúp giữ kín tên các dự án riêng tư của bạn. Proxy thực chất đang báo rằng: "Tôi không biết đây là cái gì và tôi không thể cung cấp nó cho bạn."
Bộ công cụ Go (toolchain) sẽ dừng ngay lập tức khi nhận được mã trạng thái 410 này. Nó sẽ không thử kết nối trực tiếp trừ khi bạn chỉ định rõ ràng đường dẫn nào là riêng tư.
Các giải pháp hiệu quả
1. Xác định các Domain riêng tư
Thiết lập GOPRIVATE là cách đáng tin cậy nhất để khắc phục lỗi này. Nó đóng vai trò như một danh sách bỏ qua cho các đường dẫn module. Khi một đường dẫn khớp với mẫu này, Go sẽ bỏ qua hoàn toàn proxy và cơ sở dữ liệu checksum công khai (SumDB).
Cho một kho lưu trữ cụ thể:
export GOPRIVATE=github.com/username/my-project
Cho toàn bộ công ty (Cách làm tốt nhất):
go env -w GOPRIVATE=github.com/acme-corp/*
2. Ép Git sử dụng SSH
Ngay cả sau khi đã thiết lập GOPRIVATE, quá trình build của bạn vẫn có thể thất bại với lỗi "terminal prompts disabled". Điều này xảy ra vì Go cố gắng tải các module qua HTTPS, nhưng môi trường của bạn lại sử dụng SSH key để xác thực. Bạn có thể yêu cầu Git tự động chuyển đổi giao thức:
git config --global url."git@github.com:your-org/".insteadOf "https://github.com/your-org/"
Lệnh này báo cho Git: "Bất cứ khi nào thấy yêu cầu cho https://github.com/your-org/, hãy sử dụng git@github.com:your-org/ để thay thế." Giờ đây, công cụ Go có thể sử dụng các key ~/.ssh/id_rsa hoặc ed25519 tại máy của bạn để đăng nhập.
3. Xử lý trong CI/CD và Docker
Trong các môi trường tự động như GitHub Actions hoặc Jenkins, bạn không thể sử dụng go env -w vì các môi trường này thường có tính tạm thời. Thay vào đó, hãy truyền chúng dưới dạng các biến môi trường tiêu chuẩn trong script pipeline hoặc Dockerfile của bạn.
Ví dụ đoạn mã Dockerfile:
# Thiết lập Go để bỏ qua proxy cho các module nội bộ
ENV GOPRIVATE=github.com/your-org/*
# Sử dụng Personal Access Token (PAT) để truy cập riêng tư
RUN git config --global url."https://${GITHUB_TOKEN}:x-oauth-basic@github.com/your-org/".insteadOf "https://github.com/your-org/"
Xác minh kết quả
Xác nhận các thiết lập của bạn đã hoạt động bằng cách kiểm tra môi trường:
go env GOPRIVATE
Tiếp theo, hãy thử tải module với cờ verbose. Điều này cho phép bạn thấy chính xác nơi Go đang tìm kiếm các tệp tin:
go get -v github.com/your-org/private-repo@latest
Nếu cấu hình chính xác, bạn sẽ thấy Git clone kho lưu trữ trực tiếp từ nhà cung cấp nguồn của bạn. Bạn sẽ không còn thấy các tham chiếu đến proxy.golang.org cho module cụ thể đó nữa.
Các lỗi thường gặp
- Lỗi cú pháp: Đảm bảo không có khoảng trắng xung quanh dấu
=.GOPRIVATE = github...sẽ bị lỗi trong hầu hết các shell. - Lỗi Checksum: Nếu bạn thiết lập
GONOPROXYthủ công nhưng quênGONOSUMDB, quá trình build sẽ bị lỗi. Cơ sở dữ liệu checksum công khai không thể xác minh mã nguồn riêng tư. Sử dụngGOPRIVATEtốt hơn vì nó cấu hình cả hai cài đặt cùng một lúc. - Phạm vi Wildcard: Nếu module của bạn nằm tại
github.com/org/sub-folder/repo, wildcardgithub.com/org/*sẽ bao phủ được nó. Tuy nhiên,github.com/org(không có dấu sao) có thể sẽ không hoạt động.

