1
0
Files
spring-grpc-boot4/docs/02-properties-and-versions.md
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

7.1 KiB

Properties reference, and which project owns what

Two things that cause disproportionate confusion: the exact property names, and the fact that "Spring gRPC" now means two different things with two different version numbers.


1. Boot 4.1 integration vs. the Spring gRPC project

These are separate artifacts with separate versions, and both are on your classpath.

Spring Boot gRPC integration Spring gRPC
Group org.springframework.boot org.springframework.grpc
Artifacts spring-boot-starter-grpc-server, spring-boot-starter-grpc-client, spring-boot-grpc-server, spring-boot-grpc-client, spring-boot-grpc-test spring-grpc-core
Version here 4.1.0 (the Boot version) 1.1.0
Owns auto-configuration, spring.grpc.* properties, starters, actuator/health, observation wiring the programming model: @GrpcService, @GrpcAdvice, @GrpcExceptionHandler, GrpcChannelFactory, @ImportGrpcClients, interceptor infrastructure
Managed by the Boot BOM directly the Boot BOM, via the spring-grpc.version property

Practical consequences:

  • Property names (spring.grpc.*) come from Boot 4.1, defined in GrpcServerProperties / GrpcClientProperties under org.springframework.boot.grpc.*.autoconfigure. Version them against your Boot version.
  • Annotations and interfaces come from Spring gRPC 1.1.0, in org.springframework.grpc.*. Version them against spring-grpc.version.
  • Boot 4.1 also pins grpc-java (1.80.0 here) and protobuf-java (4.34.2). Both are older than the newest releases on Maven Central — that is deliberate, and overriding them independently is how you get NoSuchMethodError between grpc-java and its Netty shading.

The older path, and why you will see it in search results

Before Boot 4, the community project shipped its own starter:

<!-- Boot 3 era -->
<dependency>
  <groupId>org.springframework.grpc</groupId>
  <artifactId>spring-grpc-spring-boot-starter</artifactId>
</dependency>

That artifact stops at 1.0.3 and is not what Boot 4 uses. On Boot 4 use the Boot starters and let the BOM manage everything:

<!-- Boot 4 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-grpc-server</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-grpc-client</artifactId>
</dependency>

Most blog posts and Stack Overflow answers you find will be describing the older artifact. The programming model is largely the same; the dependency coordinates and the property names are not.


2. Server properties — exact names

Read from spring-boot-grpc-server-4.1.0.jar's configuration metadata. This is the complete list.

Property Notes
spring.grpc.server.enabled
spring.grpc.server.port -1 disables the network server (in-process only); 0 picks an ephemeral port
spring.grpc.server.address
spring.grpc.server.inprocess.name inprocess, one word — not in-process
spring.grpc.server.inbound.message.max-size the 4 MB default, for incoming requests
spring.grpc.server.inbound.metadata.max-size header size limit
spring.grpc.server.shutdown.grace-period
spring.grpc.server.keepalive.time
spring.grpc.server.keepalive.timeout
spring.grpc.server.keepalive.permit.time minimum client ping interval the server tolerates
spring.grpc.server.keepalive.permit.without-calls
spring.grpc.server.keepalive.connection.max-age
spring.grpc.server.keepalive.connection.max-idle-time
spring.grpc.server.keepalive.connection.grace-period
spring.grpc.server.ssl.enabled / .bundle / .client-auth / .secure uses Boot SSL bundles
spring.grpc.server.health.enabled standard gRPC health service
spring.grpc.server.health.service
spring.grpc.server.health.include-overall-health
spring.grpc.server.health.status.mapping / .order actuator status → gRPC serving status
spring.grpc.server.health.schedule.enabled / .delay / .period
spring.grpc.server.health.services.validate-membership
spring.grpc.server.reflection.enabled needed for grpcurl without local .proto files
spring.grpc.server.observation.enabled Micrometer observations
spring.grpc.server.netty.transport
spring.grpc.server.netty.domain-socket-path
spring.grpc.server.servlet.enabled / .validate-http2 gRPC over the servlet container
spring.grpc.server.security.csrf.enabled
spring.grpc.server.factory.enabled

3. Client properties — exact names

The client side is a map keyed by channel name:

spring.grpc.client.channel.<name>.<property>

channel, singular. channels is wrong and produces no error — see below.

Property Notes
spring.grpc.client.channel.<name>.target target, not address
spring.grpc.client.channel.<name>.user-agent
spring.grpc.client.channel.<name>.bypass-certificate-validation test/dev only
spring.grpc.client.channel.<name>.default.deadline the default deadline gRPC otherwise lacks
spring.grpc.client.channel.<name>.default.load-balancing-policy e.g. round_robin (default is pick_first)
spring.grpc.client.channel.<name>.inbound.message.max-size 4 MB default, for incoming responses
spring.grpc.client.channel.<name>.inbound.metadata.max-size
spring.grpc.client.channel.<name>.keepalive.time / .timeout / .without-calls
spring.grpc.client.channel.<name>.idle.timeout
spring.grpc.client.channel.<name>.ssl.enabled / .bundle
spring.grpc.client.channel.<name>.health.enabled / .service-name client-side health checking
spring.grpc.client.channel.<name>.service-config.* retry, load balancing, throttling
spring.grpc.client.enabled
spring.grpc.client.inprocess.enabled register the in-process channel factory
spring.grpc.client.observation.enabled
spring.grpc.client.channelfactory.enabled

service-config maps to the gRPC service config record with loadbalancing, method, retrythrottling and healthcheck sections.

4. The two mistakes, and their symptoms

Wrong Right Symptom
spring.grpc.server.in-process.name spring.grpc.server.inprocess.name property silently ignored; server never binds in-process
spring.grpc.client.channels.x.address spring.grpc.client.channel.x.target UNAVAILABLE: Unable to resolve host x / UnknownHostException: x

The second is the expensive one. An unmatched channel name is handed to the DNS resolver as a literal target, so the error names your logical channel as if it were a hostname — and sends you to investigate DNS, service discovery and networking instead of a typo. Both cost real time while building this repository.

Guard against it: add spring-boot-configuration-processor and your IDE will flag unknown spring.grpc.* keys. It will not catch a wrong value inside the channel.<name> map (the keys there are arbitrary), but it catches everything else.