Sửa lỗi 'gpg failed to sign the data' Khi Commit Trong VS Code

intermediate💻 VS Code2026-07-17| VS Code (mọi phiên bản), Git 2.x, macOS / Linux / Windows (WSL2), GPG 2.x

Error Message

error: gpg failed to sign the data fatal: failed to write commit object
#git#gpg#commit-signing#source-control

Lỗi Gặp Phải

Bạn stage các thay đổi trong VS Code, nhấn commit — và thay vì một commit sạch, bạn nhận được:

error: gpg failed to sign the data
fatal: failed to write commit object

Panel Source Control hiển thị lỗi chung chung. Không có hộp thoại nhập passphrase, không có gợi ý về nguyên nhân. Điều khó chịu là: commit tương tự có thể chạy bình thường từ terminal thông thường. Terminal tích hợp và luồng commit GUI của VS Code thường là thủ phạm — chúng không phải lúc nào cũng kế thừa đầy đủ môi trường shell.

Nguyên Nhân

Khi bạn đặt commit.gpgsign = true trong Git config, mọi commit đều phải được ký. Có một số cách khiến điều này bị lỗi:

  • GPG agent không chạy hoặc đã bị crash
  • GPG_TTY không được đặt, khiến GPG không thể hiển thị hộp thoại nhập passphrase
  • Chương trình pinentry không thể hiển thị hộp thoại (phổ biến trong ngữ cảnh terminal của VS Code)
  • Signing key được cấu hình không tồn tại hoặc đã hết hạn
  • Trên macOS: pinentry-mac của GPG Suite chưa được kết nối đúng cách

VS Code làm cho việc debug trở nên khó khăn hơn. Terminal tích hợp và luồng commit GUI không phải lúc nào cũng kế thừa đầy đủ môi trường shell — điều này có nghĩa là GPG_TTY không được đặt và agent socket có thể bị thiếu một cách âm thầm.

Cách Sửa 1: Khởi Động Lại GPG Agent

Bắt đầu từ đây. Tắt agent và để nó tự khởi động lại ở lần gọi GPG tiếp theo:

gpgconf --kill gpg-agent
gpg-agent --daemon

Thử commit lại. Nếu agent bị crash hoặc rơi vào trạng thái lỗi, bước này thường là tất cả những gì cần làm.

Cách Sửa 2: Đặt GPG_TTY Trong Shell Profile

GPG cần một TTY để hiển thị hộp thoại nhập passphrase. Trong terminal tích hợp của VS Code, GPG_TTY thường không được đặt — khiến quá trình ký thất bại âm thầm.

Thêm dòng này vào ~/.bashrc, ~/.zshrc, hoặc ~/.bash_profile:

export GPG_TTY=$(tty)

Tải lại shell:

source ~/.zshrc   # hoặc ~/.bashrc

Mở terminal VS Code mới và thử commit lại. Trên Linux, đây là cách sửa phổ biến nhất.

Cách Sửa 3: Chuyển Sang pinentry-tty (Linux)

Vẫn không thấy hộp thoại nhập passphrase? Chuyển sang pinentry dựa trên terminal. Trước tiên, tìm vị trí của nó trên hệ thống:

which pinentry-tty
# đường dẫn phổ biến: /usr/bin/pinentry-tty hoặc /usr/local/bin/pinentry-tty

Sau đó cấu hình và khởi động lại agent:

echo "pinentry-program /usr/bin/pinentry-tty" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Kiểm tra GPG trực tiếp trước khi động vào Git:

echo "test" | gpg --clearsign

Nếu lệnh đó hiển thị hộp thoại nhập passphrase và ký thành công, các commit trong VS Code cũng sẽ hoạt động.

Cách Sửa 4: macOS — Dùng pinentry-mac

macOS có yêu cầu riêng ở đây. Nếu không có pinentry-mac, GPG không có cách nào hiển thị hộp thoại khi được gọi từ panel Source Control của VS Code — đơn giản là không có terminal nào để hiển thị cho bạn. Cài đặt trước:

brew install pinentry-mac

Sau đó kết nối nó:

echo "pinentry-program $(which pinentry-mac)" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent

Sau bước này, bạn sẽ nhận được hộp thoại nhập passphrase kiểu macOS gốc ngay cả khi commit qua GUI — không cần terminal.

Cách Sửa 5: Kiểm Tra Signing Key

Đáng để loại trừ: có thể Git đang được cấu hình với key không tồn tại hoặc đã hết hạn. Bắt đầu bằng cách kiểm tra Git đang dùng key nào:

git config --global user.signingkey

Sau đó liệt kê những key GPG thực sự có:

gpg --list-secret-keys --keyid-format LONG

Bạn sẽ thấy output như sau:

sec   rsa4096/3AA5C34371567BD2 2021-03-01 [SC]
      ...
uid   Your Name <you@example.com>

Giá trị sau dấu / trên dòng sec là key ID của bạn. Nếu nó không khớp với Git config, hãy cập nhật:

git config --global user.signingkey 3AA5C34371567BD2

Cũng kiểm tra ngày hết hạn trong output. Key hết hạn cần được gia hạn hoặc thay thế trước khi việc ký hoạt động trở lại.

Cách Sửa 6: Commit Từ Terminal (Giải Pháp Tạm Thời)

Khi luồng commit GUI liên tục thất bại, hãy bỏ qua nó. Mở terminal tích hợp và commit trực tiếp:

git commit -m "your message"

Với GPG_TTY được đặt trong shell profile và agent đang chạy, cách này thường hoạt động. Nó tránh được vấn đề môi trường mà panel Source Control của VS Code gặp phải.

Cách Sửa 7: Tạm Thời Tắt GPG Signing

Cần đẩy code ngay bây giờ? Bỏ qua việc ký cho commit này:

git commit --no-gpg-sign -m "your message"

Hoặc tắt hoàn toàn trong khi bạn debug nguyên nhân gốc rễ:

git config --global commit.gpgsign false

Bật lại sau khi đã giải quyết xong cấu hình GPG:

git config --global commit.gpgsign true

Xác Minh Đã Sửa Xong

Trước khi kết luận, hãy chạy kiểm tra nhanh từ đầu đến cuối:

# Xác nhận GPG có thể ký và hộp thoại nhập passphrase hoạt động
echo "test" | gpg --clearsign

# Tạo một commit rỗng và kiểm tra chữ ký
git commit --allow-empty -m "test gpg signing"
git log --show-signature -1

Trong output của git log, tìm dòng:

gpg: Signature made Wed Jul 16 10:00:00 2026 JST
gpg:                using RSA key 3AA5C34371567BD2
gpg: Good signature from "Your Name <you@example.com>"

Dòng "Good signature" đó là thứ bạn cần thấy. Mọi thứ đã được kết nối đúng cách.

Phòng Tránh Tái Phát

Một vài thói quen giúp ngăn vấn đề này quay lại:

  • Thêm export GPG_TTY=$(tty) vào shell profile một cách vĩnh viễn — không chỉ cho phiên làm việc hiện tại
  • Trên macOS, dùng pinentry-mac để hộp thoại nhập passphrase hoạt động ở mọi nơi, kể cả các công cụ GUI
  • Theo dõi ngày hết hạn của key: gpg --list-keys hiển thị các ngày; đặt lịch nhắc nhở khi gia hạn
  • Trên nhiều máy, hãy import GPG key trên từng máy — chỉ sao chép Git config là không đủ
  • Cân nhắc dùng SSH signing nếu muốn ít phiền phức hơn: git config --global gpg.format ssh

Related Error Notes