Nginx: gRPC upstream handshake failed or stream reset — Решение
Клиентские gRPC-вызовы завершаются со статусом UNAVAILABLE (14) или INTERNAL (13). В журнале ошибок Nginx регистрируется сбой мультиплексирования HTTP/2 фреймов: gRPC upstream: handshake failed or stream reset by server / upstream rejected gRPC stream with code 2 (INTERNAL_ERROR).
| Схема gRPC | Директива Nginx | Причина сбоя согласования |
|---|---|---|
| gRPC без TLS (h2c) | grpc_pass grpc://... | Бэкенд ожидает зашифрованный TLS, а Nginx шлет plaintext |
| gRPC с TLS (mTLS) | grpc_pass grpcs://... | Ошибка валидации сертификата или отсутствие HTTP/2 ALPN |
| Статус Code 2 | INTERNAL_ERROR | Разрыв TCP-сессии сервером gRPC из-за несовместимости протокола |
- RPC-вызовы методов (gRPC Unary / Streaming) сбрасываются мгновенно при обращении через Nginx.
- Прямой вызов бэкенда через
grpcurlбез участия Nginx работает корректно.
- Убедитесь, что для входящего клиентского порта в Nginx включен протокол HTTP/2:
# Для Nginx 1.25.1+: server { listen 443 ssl; http2 on; server_name grpc.example.com; ... } - Если целевой микросервис gRPC работает без шифрования (h2c plaintext), используйте схему
grpc://:location /my.package.ServiceName/ { grpc_pass grpc://127.0.0.1:50051; # Обязательные gRPC таймауты и буферы: grpc_read_timeout 120s; grpc_send_timeout 120s; grpc_set_header Host $host; grpc_set_header X-Real-IP $remote_addr; } - Если бэкенд требует зашифрованный TLS (grpcs), используйте схему
grpcs://и включите передачу SNI:location / { grpc_pass grpcs://backend_grpc_tls; grpc_ssl_server_name on; grpc_ssl_name backend.internal; # При необходимости самоподписанных сертификатов: # grpc_ssl_verify off; } - Проверьте файл конфигурации:
sudo nginx -t. - Примените параметры:
sudo systemctl reload nginx.
POST с заголовком Content-Type: application/grpc. Если промежуточный WAF трансформирует или блокирует эти заголовки, gRPC-сервер сбросит стрим с кодом ошибки.Частые вопросы (FAQ)
Чем grpc_pass отличается от стандартного proxy_pass?
Директива grpc_pass использует специализированный модуль ngx_http_grpc_module, который полноценно поддерживает бинарный транспорт HTTP/2 фреймов, двунаправленный стриминг (Bi-directional streaming) и передачу gRPC Trailers (заголовков завершения статуса RPC).
Поддерживает ли Nginx gRPC Streaming?
Да, Nginx полностью поддерживает клиентский, серверный и двунаправленный (bidirectional) стриминг при условии достаточных таймаутов в директиве grpc_read_timeout.
Как протестировать gRPC эндпоинт за Nginx из консоли?
Используйте CLI утилиту grpcurl: grpcurl -insecure -v grpc.example.com:443 list.
Что означает gRPC статус UNAVAILABLE (14)?
Код 14 означает, что сервис физически недоступен, TCP-соединение не смогло установиться, либо Nginx вернул 502/503 статус при невозможности связаться с бэкендом.