SECURITY WARNING: Never run commands you don't understand. Always review code before execution. Use at your own risk.
gRPC New Added 15 October 2026

gRPC: UNAVAILABLE: DNS resolution failed for service

The channel could not turn the target into an address. Besides a plain typo, two gRPC quirks cause it: the target string uses its own URI syntax, so a scheme like http:// or a trailing path is read as part of the hostname, and C-core may use the c-ares resolver, which ignores /etc/hosts entries and search domains that ping and curl happily use. A name that resolves fine in the shell can therefore fail in the client.

Quick fix

Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.

Quick fix
# Targets are host:port, or dns:///host:port. Not http://host:port
# grpc.insecure_channel('dns:///orders.default.svc.cluster.local:50051')

# Does the name resolve on this machine, and from where?
getent hosts orders.default.svc.cluster.local
dig +short orders.default.svc.cluster.local

# Force the system resolver if c-ares is the problem (C-core languages)
export GRPC_DNS_RESOLVER=native

# See the resolver's own view
export GRPC_VERBOSITY=debug GRPC_TRACE=cares_resolver,dns_resolver

# Kubernetes: use the full service name when calling across namespaces
kubectl get svc -A | grep orders

How to diagnose gRPC errors

Every gRPC call ends with a status code, and the code tells you which layer failed. UNAVAILABLE and INTERNAL are transport: the connection, the proxy or the HTTP/2 stream, not your handler. UNAUTHENTICATED, PERMISSION_DENIED and UNIMPLEMENTED mean the request arrived and was rejected before your logic ran. INVALID_ARGUMENT, FAILED_PRECONDITION and ABORTED are your service answering deliberately. The distinction matters most for retries: UNAVAILABLE and ABORTED are safe to retry, FAILED_PRECONDITION and INVALID_ARGUMENT never are, and retrying them turns one bad request into a storm.

If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.

  1. Read the code and the message together. grpcurl -vv prints the status, the message and any google.rpc error details the server attached, which is far more than most client libraries surface by default.
  2. Establish whether the call reached your handler at all. Log at the first line of the method: if nothing appears, the failure is in the transport, the proxy or an interceptor, and reading your business logic is wasted effort.
  3. Enable the runtime's own transport logging. GRPC_GO_LOG_SEVERITY_LEVEL=info GRPC_GO_LOG_VERBOSITY_LEVEL=2 for Go, or GRPC_VERBOSITY=debug GRPC_TRACE=http,call_error for the C based implementations, exposes HTTP/2 resets and name resolution that the status code hides.
  4. Check that HTTP/2 survives the whole path. Any load balancer that terminates at layer 7 without HTTP/2 support, or an idle timeout shorter than your keepalive, produces stream resets that surface as INTERNAL or UNAVAILABLE on a service that is perfectly healthy.
  5. Confirm both sides were generated from the same .proto. A method rename, a package change or a stale generated file gives UNIMPLEMENTED, and grpcurl list against a server with reflection enabled settles it in one command.
  6. For anything size or time related, remember the limits are enforced per side: the 4 MB receive limit, the client deadline and the server's max connection age each belong to one peer, so raising one alone often just moves the failure.

Tools worth reaching for

  • grpcurl
  • grpc_health_probe
  • GRPC_GO_LOG_SEVERITY_LEVEL / GRPC_TRACE
  • buf lint && buf breaking
  • Wireshark or tcpdump with HTTP/2 decoding
  • Envoy access logs

Authoritative references

Primary documentation for this error, worth reading before applying any fix in production.

github.com github.com

Related gRPC errors

See all 17 gRPC errors →

Browse other categories

Something missing or wrong?

This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.