Lỗi ERR_HTTP2_PROTOCOL_ERROR là gì? Cách khắc phục

Advertisement
ERR_HTTP2_PROTOCOL_ERROR là gì?
ERR_HTTP2_PROTOCOL_ERROR là lỗi trên Chrome và Edge, cho biết trình duyệt đã nhận được một phản hồi HTTP/2 vi phạm quy tắc của giao thức. Trong Chromium, đây là mã lỗi mạng -337: "có lỗi giao thức HTTP/2" (there is an HTTP/2 protocol error). Chrome không có trang lỗi riêng cho nó, nên bạn sẽ thấy trang chung: "Không thể truy cập trang web này. Trang web tại … có thể tạm thời ngừng hoạt động hoặc đã chuyển vĩnh viễn sang địa chỉ web mới", với dòng ERR_HTTP2_PROTOCOL_ERROR bên dưới.
HTTP/2 là phiên bản HTTP nhanh hơn mà hầu hết các trang HTTPS hiện nay đều sử dụng. Nó nghiêm ngặt hơn HTTP/1.1: phản hồi được chia thành các khung nhị phân (binary frame), header tuân theo quy tắc chính xác, và kích thước khai báo của phản hồi phải khớp với dữ liệu thực sự nhận được. Khi Chrome thấy một phản hồi vi phạm các quy tắc đó, ví dụ phản hồi dừng giữa chừng hoặc chứa header bị cấm, nó coi toàn bộ phản hồi là sai định dạng và loại bỏ.
Lập trình viên thường thấy lỗi này trong console của DevTools dưới dạng net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK). Sự kết hợp đó là một manh mối rõ ràng: máy chủ đã trả lời 200, nhưng phần thân phản hồi chưa bao giờ đến nguyên vẹn.
Những gì HTTP/2 coi là sai định dạng
Chuẩn HTTP/2 (RFC 9113) liệt kê các lỗi khiến một phản hồi bị coi là sai định dạng, và một luồng (stream) bị reset trước khi hoàn tất cũng thất bại. Đây là những vấn đề đứng sau hầu hết các lỗi trong thực tế:
| Quy tắc | Điều gì vi phạm nó |
|---|---|
| Content-Length phải bằng kích thước phần thân | Máy chủ hoặc plugin khai báo một kích thước nhưng gửi kích thước khác, ví dụ khi đầu ra được nén sau khi độ dài đã được đặt |
| Phản hồi phải kết thúc gọn gàng | Máy chủ, proxy hoặc ứng dụng ngừng gửi giữa chừng |
| Không có header dành riêng cho kết nối | Connection, Keep-Alive, Proxy-Connection, Transfer-Encoding hoặc Upgrade được gửi trong phản hồi HTTP/2 |
| Tên trường phải viết thường | Tên header có chữ in hoa được chuyển thẳng sang HTTP/2 |
| Giá trị header hợp lệ | Ký tự xuống dòng hoặc ký tự bị cấm khác bên trong giá trị header |
| Dòng :status hợp lệ | Mã trạng thái bị thiếu hoặc không đọc được |
Advertisement
Nguyên nhân gây ra lỗi ERR_HTTP2_PROTOCOL_ERROR
Hầu hết các trường hợp đến từ phía máy chủ, nhưng một vài thứ trên chính máy tính của bạn cũng có thể làm hỏng phản hồi trên đường đến:
Trên máy chủ: phản hồi bị cắt giữa chừng (proxy hết dung lượng ổ đĩa hoặc không ghi được tệp tạm, ứng dụng bị crash khi đang truyền dữ liệu, hết thời gian chờ), giá trị Content-Length sai, header bị cấm hoặc không hợp lệ, và hỗ trợ HTTP/2 bị lỗi trong cấu hình máy chủ hoặc CDN cũ.
Ở phía bạn: phần mềm diệt virus hoặc tường lửa kiểm tra HTTPS và viết lại phản hồi, tiện ích mở rộng của trình duyệt sửa đổi yêu cầu hoặc phản hồi, bản sao của trang trong bộ nhớ đệm bị hỏng, và đôi khi là phiên bản Chrome đã lỗi thời.
Cách 1: Tải lại cứng và thử chế độ Ẩn danh
Nhấn Ctrl + Shift + R (Mac: Cmd + Shift + R) để tải lại mà không dùng bộ nhớ đệm. Một phản hồi bị cắt một lần có thể đến bình thường trong lần thử tiếp theo.
Sau đó mở trang trong cửa sổ Ẩn danh (Ctrl + Shift + N, Mac Cmd + Shift + N). Chế độ Ẩn danh không có cookie, không có bộ nhớ đệm từ hồ sơ thông thường của bạn, và tiện ích mở rộng mặc định bị tắt. Nếu trang tải được ở đó, Cách 2 hoặc Cách 3 sẽ giải quyết vấn đề trong cửa sổ thông thường.
Advertisement
Cách 2: Xóa bộ nhớ đệm và cookie của trang web đó
Một bản sao bị hỏng trong bộ nhớ đệm hoặc một cookie phình to có thể gây lỗi liên tục trên một trang web. Chỉ xóa dữ liệu của trang đó: nhấp vào biểu tượng bên trái thanh địa chỉ → Cookie và dữ liệu trang web (Cookies and site data) (hoặc Cài đặt trang web) → xóa dữ liệu, rồi tải lại. Để dọn dẹp rộng hơn, nhấn Ctrl + Shift + Delete và xóa Hình ảnh và tệp được lưu trong bộ nhớ đệm (Cached images and files) của vài ngày gần đây.
Cách 3: Tạm dừng quét HTTPS của phần mềm diệt virus và tiện ích mở rộng
Phần mềm bảo mật giải mã và kiểm tra HTTPS nằm ở giữa mọi kết nối HTTP/2. Nếu cách nó xử lý HTTP/2 bị lỗi hoặc đã lỗi thời, nó có thể chuyển tiếp những phản hồi mà Chrome coi là sai định dạng. Chỉ tắt tính năng quét HTTPS (thường có tên HTTPS scanning, Web Shield, SSL/TLS protocol filtering hoặc Scan encrypted connections) rồi tải lại. Nếu cách đó khắc phục được, hãy cập nhật phần mềm diệt virus và thêm ngoại lệ cho trang web.
Tiếp theo, tắt tất cả tiện ích mở rộng tại chrome://extensions, tải lại, rồi bật lại từng cái một. Trình chặn quảng cáo, công cụ bảo vệ quyền riêng tư và bất cứ thứ gì chỉnh sửa header là những nghi phạm thường gặp.
Advertisement
Cách 4: Cập nhật Chrome và kiểm tra trên trình duyệt khác
Mở chrome://settings/help để cài đặt bản cập nhật đang chờ, sau đó khởi động lại trình duyệt. Rồi mở cùng trang đó trên Firefox hoặc Safari. Nếu trang lỗi ở mọi nơi, trang web đang bị hỏng và chỉ chủ trang mới khắc phục được. Nếu chỉ Chrome hoặc Edge bị lỗi, nguyên nhân thường vẫn nằm ở trang web, vì Chrome từ chối HTTP/2 sai định dạng nghiêm ngặt nhất, nhưng Cách 2 và Cách 3 vẫn đáng để thử lại.
Cách 5: Kiểm tra trang khi không dùng HTTP/2
Chrome có thể được khởi động với HTTP/2 bị tắt, giúp bạn biết chắc chắn HTTP/2 có phải là vấn đề hay không. Đóng mọi cửa sổ Chrome trước, rồi khởi động nó từ terminal:
# Windows (Command Prompt)
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-http2
# macOS (Terminal)
open -a "Google Chrome" --args --disable-http2Nếu trang tải được trong cửa sổ đó, phản hồi HTTP/2 của trang web đang bị sai định dạng và chủ trang cần khắc phục. Sau đó hãy đóng Chrome và mở lại như bình thường. Cờ này chỉ áp dụng cho lần khởi chạy đó.
Advertisement
Dành cho chủ website: Khắc phục lỗi giao thức HTTP/2
Nếu khách truy cập trên nhiều mạng và trình duyệt khác nhau đều báo lỗi, vấn đề nằm trong hệ thống của bạn. Ba bước kiểm tra sau tìm ra gần như tất cả nguyên nhân.
1. Tái hiện lỗi bằng curl
# HTTP/2: theo dõi phần cuối của đầu ra
curl -sv --http2 https://example.com/broken-page -o /dev/null
# Một luồng bị lỗi sẽ kết thúc bằng dòng tương tự:
# HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
# (curl 8.19+: HTTP/2 stream 1 reset by server (error 0x1 PROTOCOL_ERROR))
# Cùng URL qua HTTP/1.1 để so sánh
curl -sv --http1.1 https://example.com/broken-page -o /dev/nullNếu HTTP/1.1 hoạt động còn HTTP/2 thất bại, bạn đã xác nhận được lỗi. Hãy so sánh header phản hồi giữa hai lần, và ghi lại số byte nhận được trước khi luồng bị đứt. Công cụ Kiểm Tra Header HTTP cũng hiển thị các header mà trang của bạn gửi khi nhìn từ bên ngoài mạng của bạn.
2. Kiểm tra phản hồi bị cắt giữa chừng
Nguyên nhân phổ biến nhất ở phía máy chủ là phản hồi đã bắt đầu (trạng thái 200, header đã gửi) rồi dừng sớm. nginx lưu tạm các phản hồi lớn từ ứng dụng của bạn vào tệp tạm, và nếu ổ đĩa đầy hoặc nginx không ghi được vào thư mục tạm, phản hồi sẽ kết thúc sớm và trình duyệt báo lỗi giao thức. Hãy kiểm tra:
df -h # có ổ đĩa nào bị đầy không?
sudo grep -E "No space left|Permission denied" /var/log/nginx/error.log | tail
ls -ld /var/lib/nginx/proxy /var/lib/nginx/fastcgi # thư mục tạm trên Debian/Ubuntu; chủ sở hữu phải trùng với user của nginxHãy kiểm tra cả bản thân ứng dụng: một tiến trình PHP hoặc Node bị crash, hết thời gian chờ hoặc chạm giới hạn bộ nhớ trong khi truyền một trang hay tệp tải xuống lớn cũng tạo ra kết quả tương tự. Log của ứng dụng quanh thời điểm xảy ra lỗi thường cho thấy điều đó.
3. Sửa Content-Length và các header bị cấm
Content-Length: hãy để máy chủ tự tính. Đừng tự đặt giá trị này trong mã ứng dụng nếu một plugin, middleware hoặc máy chủ web cũng nén hoặc sửa đổi đầu ra, vì khi đó độ dài khai báo sẽ không còn khớp với số byte được gửi. Độ dài được đặt trong mã PHP trong khi một plugin hoặc thiết lập PHP cũng nén đầu ra là một cách điều này xảy ra trên các trang WordPress.
Header dành riêng cho kết nối: xóa đoạn mã đặt
Connection,Keep-Alive,Transfer-EncodinghoặcUpgradetrên phản hồi. HTTP/2 cấm chúng, và mặc dù nginx tự loại bỏ phần lớn các header này, một số máy chủ ứng dụng và proxy thì không.Giá trị header: đảm bảo không header nào chứa ký tự xuống dòng hoặc ký tự điều khiển. Điều này thường đến từ dữ liệu người dùng nhập được đặt vào header, chẳng hạn tên tệp trong
Content-Disposition.CDN phía trước: nếu bạn dùng Cloudflare hoặc CDN khác, hãy kiểm tra trực tiếp máy chủ gốc (bằng curl
--resolvehoặc một mục trong tệp hosts) để biết lỗi đến từ máy chủ gốc hay từ CDN.
ERR_HTTP2_PROTOCOL_ERROR khác gì các lỗi tương tự
| Lỗi | Mã | Điều đã xảy ra |
|---|---|---|
| ERR_HTTP2_PROTOCOL_ERROR | -337 | Một phản hồi HTTP/2 vi phạm quy tắc giao thức |
| ERR_QUIC_PROTOCOL_ERROR | -356 | Cùng loại lỗi nhưng qua HTTP/3 (QUIC) |
| ERR_SSL_PROTOCOL_ERROR | -107 | Quá trình bắt tay HTTPS (TLS) thất bại trước khi HTTP/2 bắt đầu |
| ERR_CONNECTION_CLOSED | -100 | Kết nối bị đóng trước khi trang được gửi đến |
| ERR_EMPTY_RESPONSE | -324 | Máy chủ hoàn toàn không gửi gì |
Hướng dẫn chi tiết: ERR_QUIC_PROTOCOL_ERROR, ERR_SSL_PROTOCOL_ERROR, ERR_CONNECTION_CLOSED và ERR_EMPTY_RESPONSE. Để kiểm tra chứng chỉ và thiết lập HTTPS của một trang web từ bên ngoài, hãy dùng Kiểm Tra Chứng Chỉ SSL.
Xem các header mà trang của bạn thực sự gửi
Công cụ Kiểm Tra Header HTTP của DNS Robot tải bất kỳ URL nào từ máy chủ của chúng tôi và liệt kê mã trạng thái cùng mọi header phản hồi, giúp bạn dễ dàng phát hiện header bị cấm hoặc sai định dạng.
Thử Kiểm Tra Header HTTPAdvertisement
Câu hỏi thường gặp
Nó có nghĩa là Chrome nhận được một phản hồi HTTP/2 vi phạm quy tắc của giao thức, ví dụ phản hồi kết thúc sớm, khai báo sai kích thước, hoặc chứa header bị cấm, nên nó loại bỏ phản hồi đó. Trong Chromium, đây là mã lỗi mạng -337.