Go Error Semantics Across Service Boundaries: Typed Errors, Sentinel Values, and the gRPC Status Translation Problem
Go's error model is deliberately minimal: error is an interface with a single Error() string method. That minimalism is a feature inside a package, but it becomes an operational liability the moment an error crosses a network boundary. In a gRPC microservice graph, the gap between what your domain model knows about a failure and what the wire protocol can carry is where debugging hours disappear and retry storms start.
This article examines the mechanics of that translation problem, the failure modes that result from ignoring it, and a typed error propagation pattern that survives serialization without leaking internals.
Why Error Identity Breaks at the Wire
Inside a single Go process, errors have identity. You can use errors.Is and errors.As to walk an error chain and make precise branching decisions.…