Skip to content

How to Fix gRPC Unavailable / Deadline Exceeded Error

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about How to Fix gRPC Unavailable / Deadline Exceeded Error. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Your gRPC client receives:

status = StatusCode.UNAVAILABLE
details = "connection closed before server preface received"

Or:

status = StatusCode.DEADLINE_EXCEEDED
details = "Deadline Exceeded"

The gRPC server is unreachable, not responding, or the client deadline expired before the server completed the request.

Quick Fix

1. Check the gRPC server health

gRPC servers typically expose a health check endpoint:

# Use grpc_health_probe
grpc_health_probe -addr=localhost:50051

# Expected output: "serving"

If the probe fails, the server is not accepting connections.

2. Increase the client deadline

The default deadline may be too short:

// Go gRPC client
// Wrong — no deadline (uses very short default)
resp, err := client.GetUser(ctx, &req)

// Right — set a reasonable deadline
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
resp, err := client.GetUser(ctx, &req)
# Python gRPC client
# Wrong — no deadline
response = stub.GetUser(request)

# Right — set deadline
import grpc
channel = grpc.insecure_channel('localhost:50051')
stub = GreeterStub(channel)
response = stub.GetUser(request, timeout=30)

3. Configure keepalive

gRPC requires keepalive pings to maintain long-lived connections:

// Server-side keepalive
import "google.golang.org/grpc/keepalive"

var kaep = keepalive.EnforcementPolicy{
    MinTime:             5 * time.Second,
    PermitWithoutStream: true,
}

var kasp = keepalive.ServerParameters{
    Time:    10 * time.Second,
    Timeout: 5 * time.Second,
}

s := grpc.NewServer(
    grpc.KeepaliveEnforcementPolicy(kaep),
    grpc.KeepaliveParams(kasp),
)
// Client-side keepalive
var kacp = keepalive.ClientParameters{
    Time:                10 * time.Second,
    Timeout:             5 * time.Second,
    PermitWithoutStream: true,
}

conn, _ := grpc.Dial("localhost:50051",
    grpc.WithKeepaliveParams(kacp),
    grpc.WithInsecure(),
)

4. Fix load balancer configuration

gRPC uses HTTP/2 and requires specific load balancer support:

# Envoy config for gRPC
static_resources:
  listeners:
  - address:
      socket_address: { address: 0.0.0.0, port_value: 443 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          http2_protocol_options: {}
          upgrade_configs:
          - upgrade_type: CONNECT

5. Set up retry policy

// Client-side retry with backoff
import "google.golang.org/grpc/backoff"

conn, _ := grpc.Dial("localhost:50051",
    grpc.WithConnectParams(grpc.ConnectParams{
        Backoff: backoff.Config{
            BaseDelay:  1.0 * time.Second,
            Multiplier: 1.6,
            MaxDelay:   120 * time.Second,
        },
        MinConnectTimeout: 5 * time.Second,
    }),
)

6. Enable gRPC in the proxy

Nginx 1.14+ supports gRPC proxying:

location / {
    grpc_pass grpc://backend:50051;
}

For AWS ALB, enable HTTP/2 and use the gRPC target group.

Prevention

  • Always set explicit deadlines (30-60s) on gRPC client calls.
  • Configure keepalive on both client and server.
  • Use a gRPC-aware load balancer (Envoy, NGINX, or ALB).
  • Implement client-side retry with exponential backoff.
  • Monitor gRPC error rates per status code.

Common Mistakes with grpc error

  1. Using foldl instead of foldl' causing stack overflow on large lists
  2. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  3. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable

These mistakes appear frequently in real-world API code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What is the difference between UNAVAILABLE and DEADLINE_EXCEEDED?

UNAVAILABLE means the server is unreachable or the connection failed (network issue, server down). DEADLINE_EXCEEDED means the server was reachable but did not respond in time.

Why does gRPC fail with "connection closed before server preface received"?

This typically means the server does not support HTTP/2, or a proxy is interfering with the gRPC connection. Ensure the server and all intermediaries support HTTP/2.

Can I use gRPC with a standard HTTP load balancer?

Most HTTP load balancers only support HTTP/1.1. gRPC requires HTTP/2. Use a gRPC-aware load balancer like Envoy, NGINX (1.14+), or a cloud load balancer with HTTP/2 support.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro