1
0
Ankur 8547981634 Spring gRPC on Spring Boot 4: four call types, exception mapping, and a symptom-first troubleshooting suite
Companion code for the ankurm.com guide. Verified on Spring Boot 4.1.0, spring-grpc 1.1.0,
grpc-java 1.80.0, protobuf-java 4.34.2, JDK 25.0.3. results-full.txt is unedited mvn test
output: 11 tests, 0 failures. No installs needed - protoc and the gRPC codegen plugin resolve
as Maven artifacts, and every test uses the in-process transport.

_01_basics       all four call types and how their failure modes differ: iterator semantics on
                 server streaming, the half-close that client streaming hangs without, and the
                 independence of the two streams in bidi.
_02_troubleshooting
                 four failures reproduced then fixed - the 4 MB message limit and which side
                 enforces it, the absent default deadline, cancellation that never interrupts a
                 thread, and errors that arrive as UNKNOWN with no description.
_03_exceptions   @GrpcAdvice / @GrpcExceptionHandler: domain exception to NOT_FOUND with
                 trailers, validation to INVALID_ARGUMENT, and a catch-all that returns a
                 deliberate INTERNAL without leaking the original message across the boundary.

docs/01          symptom-first troubleshooting index, each entry marked [tested] or [documented]
docs/02          complete spring.grpc.* property reference, and the split between the Boot 4.1
                 integration (org.springframework.boot, version 4.1.0, owns properties and
                 auto-configuration) and the Spring gRPC project (org.springframework.grpc,
                 version 1.1.0, owns the programming model). The older standalone
                 spring-grpc-spring-boot-starter stops at 1.0.3 and is what most search results
                 describe.

Findings worth the commit message
  - The in-process transport CANNOT enforce message size limits: it passes messages by
    reference and never serialises them. A 4 MB + 1 KB message goes through cleanly in tests
    and fails in production with RESOURCE_EXHAUSTED. The test asserts this rather than
    pretending otherwise. Same blind spot covers compression, TLS, keepalive and LB.
  - Two property names cost real time while writing this:
    spring.grpc.server.inprocess.name (not in-process) and
    spring.grpc.client.channel.<n>.target (singular channel, and target not address).
    The second failure surfaces as UnknownHostException on the channel NAME.
  - gRPC still has no default deadline, and cancellation only sets a Context flag.
2026-07-31 23:05:02 +05:30

Spring gRPC with Spring Boot 4

Companion repository for Spring gRPC with Spring Boot 4 on ankurm.com.

The post covers the concepts. This repository adds the part that is hard to find written down: a symptom-first troubleshooting guide, with the failures reproduced as tests wherever a test can honestly reproduce them.

Verified against Spring Boot 4.1.0, spring-grpc 1.1.0, grpc-java 1.80.0, protobuf-java 4.34.2, JDK 25.0.3. Full output in results-full.txt.


Quick start

Nothing to install — protoc and the gRPC codegen plugin are resolved as Maven artifacts, and every test runs over the in-process transport, so no port is bound.

git clone https://ankurm.com/git.app/asmhatre/spring-grpc-boot4.git
cd spring-grpc-boot4
mvn test

8 tests, a few seconds.


What is here

Test Covers
FourCallTypesTest Unary, server streaming, client streaming, bidirectional — and how their failure modes differ
HardToDiagnoseTest Four failures reproduced and fixed: message size limits, missing deadlines, unobserved cancellation, useless error statuses
ExceptionMappingTest @GrpcAdvice / @GrpcExceptionHandler — domain exception → NOT_FOUND, validation → INVALID_ARGUMENT, catch-all → INTERNAL without leaking detail
Document Covers
Troubleshooting Symptom-first index: every entry starts from the error message you actually see
Properties and versions Complete spring.grpc.* reference, and which of the two projects owns what

Exception mapping

OrderExceptionAdvice is the gRPC analogue of @RestControllerAdvice. The service throws plain domain exceptions and never mentions Status:

@GrpcAdvice
public class OrderExceptionAdvice {

    @GrpcExceptionHandler(OrderNotFoundException.class)
    public StatusException handleNotFound(OrderNotFoundException ex) {
        Metadata trailers = new Metadata();
        trailers.put(REASON_KEY, "ORDER_NOT_FOUND");
        return Status.NOT_FOUND.withDescription(ex.getMessage()).asException(trailers);
    }
}

Without it, every domain failure arrives as UNKNOWN with a null description — no code to branch on and no message to read.

The service itself (OrderServiceImpl) is heavily commented and is where the correct patterns live — cancellation checks, half-close handling, StreamObserver thread-safety, structured errors.


Five findings

  1. gRPC is a first-class Boot starter now, and "Spring gRPC" means two things. org.springframework.boot:spring-boot-starter-grpc-server (version 4.1.0) owns auto-configuration and every spring.grpc.* property; org.springframework.grpc:spring-grpc-core (version 1.1.0) owns the programming model — @GrpcService, @GrpcAdvice, GrpcChannelFactory. The older standalone spring-grpc-spring-boot-starter stops at 1.0.3 and is what most search results describe. See docs/02.
  2. The in-process transport cannot enforce message size limits. It passes messages by reference and never serialises them, so a 4 MB + 1 KB message sails through — and fails in production with RESOURCE_EXHAUSTED. Asserted in the test suite. The same blind spot covers compression, TLS, keepalive and load balancing.
  3. Two property names that cost real time. spring.grpc.server.inprocess.name (not in-process) and spring.grpc.client.channel.<n>.target (singular channel, and target not address). Getting the second wrong yields UnknownHostException on the channel name, which sends you to look at DNS.
  4. gRPC has no default deadline. A call without one waits forever. This is the single most common cause of a gRPC service that silently stops responding.
  5. Cancellation does not interrupt your thread. It sets a Context flag. A server that never checks it keeps working for a client that left ten minutes ago.

Reference machine

AMD Ryzen 5 5600U, Windows 11, java 25.0.3+9-LTS-195, Maven 3.9.9.

Licence

MIT. See LICENSE.

Description
Spring gRPC on Spring Boot 4.1: all four call types plus a symptom-first troubleshooting suite - message size limits, missing deadlines, unobserved cancellation, useless error statuses. Runs over the in-process transport, no installs. Companion code for the ankurm.com guide.
Readme 82 KiB
Languages
Java 100%