gRPC Knowledge Patch
Apply this skill when changing gRPC transports, generated tooling, Python
servers, Go authorization, Java channels, xDS, or load-balancing behavior.
Working method
- Identify the implementation, package versions, transport, and deployment
platform involved in the task.
- Read the matching reference before relying on a default, dependency bound,
xDS matcher, server limit, or dynamically created channel.
- Treat security-related defaults as behavior changes even when application
code did not opt in explicitly.
- Preserve intentional compatibility overrides until integration and
interoperability tests show they are no longer needed.
- Test both success and failure paths for interceptors, name resolution,
authorization, connection setup, and control-plane resource loading.
- Prefer the project's manifests, lockfiles, code, and observed runtime
behavior when they conflict with assumptions outside this patch.
Reference index
| Reference |
Topics |
| transport-security-and-tooling.md |
Post-quantum TLS, HTTP/2 frame-flood and stream limits, Android server TLS 1.3, Linux ARM64 Grpc.Tools packaging |
| python-apis-runtime-and-dependencies.md |
Async status aborts, custom interceptor failures, protobuf bounds, Python 3.15 |
| authorization-and-xds.md |
Go RBAC matchers and header validation, deprecated source_ip, ORCA-to-LRS propagation, aggregate-cluster labels, control-plane connections |
| java-channel-and-configuration.md |
RFC 3986 parsing, per-channel resolver registries, numeric service config, child-channel configuration |
Breaking changes, defaults, and compatibility risks
TLS negotiation changes without an opt-in
- Expect new gRPC Core TLS connections to use post-quantum cryptography in key
exchange by default.
- Recheck TLS inspection, policy enforcement, interoperability, and latency
assumptions when transport behavior changes despite unchanged application
configuration.
- On Android, account for TLS 1.3 on OkHttp-based gRPC Java servers as well as
clients. Do not retain a server-only assumption that TLS 1.3 is unavailable.
- Read transport security and tooling
before changing TLS policy or transport dependencies.
Java URI parsing now follows RFC 3986 by default
- Re-test targets containing reserved characters, percent escapes, unusual
authorities, or path-like components.
- Do not assume parser behavior remains legacy-compatible merely because no
parsing option was enabled by the application.
- Keep target parsing tests close to custom resolvers and channel construction.
gRPC-Go throttles HTTP/2 control-frame floods
- Expect a server to stop reading from a connection after the control-buffer
throttle reaches its limit.
- The default threshold is 100 frames; DATA and HEADERS frames do not count
toward it.
- Override the threshold only through
GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT, and validate the chosen
value under legitimate high-control-frame workloads as well as abusive ones.
export GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT=200
Java Netty servers enforce stream limits during setup
- Expect the client-initiated stream limit to apply proactively from connection
startup rather than only after
SETTINGS_ACK.
- Re-test clients that open streams aggressively during connection setup; the
earlier timing window no longer permits them to bypass the configured limit.
- Include pre- and post-acknowledgment cases in transport-limit regression tests.
xDS DENY rules enforce more matchers and validate header names
- Treat
Metadata and RequestedServerName as enforced gRPC-Go xDS RBAC
permission fields. The prior ignored behavior could let DENY rules fail open.
- Expect nested
Principal and Permission header matchers, including
non-lowercase names, to be validated and canonicalized.
- Reject
:scheme and grpc--prefixed matchers, and treat host as
:authority.
- Re-test mixed-case names that previously matched nothing and could let a DENY
rule fail open.
- Continue accepting deprecated
source_ip principals as equivalent to
direct_remote_ip, but generate the current spelling in new configuration.
Java xDS control-plane connections are channel-scoped again
- Do not assume xDS control-plane connections are reused across channels.
- Reuse across many targets could exhaust the control plane's
MAX_CONCURRENT_STREAMS, leaving new channels stuck in name resolution while
waiting for resources.
- Capacity-test many-channel deployments and diagnose stalled resolution with
both channel state and control-plane stream limits in view.
Python protobuf compatibility has two distinct paths
- Treat 7.35.1 as the lower bound for the main Python protobuf dependency.
- Do not apply that bound indiscriminately to the separate v1.83.x
grpc-status backport, whose relaxed constraint retains protobuf 6.x
compatibility.
- Resolve the package actually constraining protobuf before changing a lockfile.
Aggregate-cluster metric labels identify the leaf
- Expect gRPC Java xDS metrics for aggregate clusters to use the leaf cluster
name as the backend-service label.
- Update dashboards, alerts, joins, and cardinality expectations that grouped
these metrics by the aggregate cluster name.
New APIs and capability quick reference
Abort async Python RPCs with a status object
Use the status-based abort method directly from grpc.aio.ServicerContext:
async def handle(request, context):
await context.abort_with_status(status)
The method is part of the abstract async context interface. Keep custom context
implementations compatible with that interface, and test that control flow ends
as expected after the awaited abort.
Isolate Java name resolution per channel
Use the Grpc.newChannelBuilder overload that accepts a
NameResolverRegistry when a channel must not depend on the process-global
registry. This supports isolated tests, embedded runtimes, and applications
whose channels require different resolver sets.
Customize dynamically created Java child channels
Use ChildChannelConfigurer to intercept child channels created by load
balancers. Apply channel-specific interceptors or credential changes there
instead of assuming top-level channel customization reaches every dynamic child.
Accept ordinary Java numeric service-config values
Pass integer-looking values such as maxAttempts: 4 and
backoffMultiplier: 2 to defaultServiceConfig() without converting them to
decimal literals first. Validation accepts any Number and normalizes accepted
values to Double.
Select ORCA metrics for LRS propagation
Expect ORCA-to-LRS propagation to be enabled by default in gRPC Java. Under
gRFC A85, use xDS configuration to select which fields from backend ORCA metric
reports are copied into LRS load reports.
Use current Python and Linux ARM64 support
- Include Python 3.15 in supported-runtime testing where the application adopts
that interpreter.
- On Linux ARM64, account for the
Grpc.Tools move to manylinux_2_28 and the
maximum-page-size alignment fix for its bundled protoc executable.
- Re-evaluate base-image compatibility when upgrading build tooling, even when
generated source is unchanged.
Implementation checklists
Transport and packaging
- Read transport-security-and-tooling.md.
- Exercise TLS handshakes against every relevant peer and middlebox.
- Load-test the HTTP/2 control-frame threshold before overriding it.
- Test the Java Netty stream limit during connection startup.
- Run the packaged
protoc on the actual Linux ARM64 build image.
- Verify Android server and client TLS expectations separately.
Python
- Read python-apis-runtime-and-dependencies.md.
- Inspect both the gRPC and
grpc-status dependency paths before resolving
protobuf constraints.
- Await status-based aborts and update custom async contexts.
- Test interceptor exceptions for every unary and streaming call shape in use.
- Add Python 3.15 to CI only after native and generated dependencies agree.
Go authorization and server protection
- Read authorization-and-xds.md and the
Go section of transport-security-and-tooling.md.
- Re-run DENY-policy tests for metadata, requested server names, nested headers,
case normalization, reserved prefixes, and
host mapping.
- Accept legacy
source_ip input while emitting direct_remote_ip in new xDS
configuration.
- Observe connection behavior at the default flood threshold before tuning it.
Java channels, xDS, and load balancing
- Read java-channel-and-configuration.md
for channel construction and parsing.
- Read authorization-and-xds.md for xDS
telemetry, labels, and control-plane connection behavior.
- Test custom target strings under RFC 3986 parsing.
- Supply a channel-local resolver registry where global state is inappropriate.
- Verify child-channel interceptors and credentials on dynamic children.
- Update metric queries to use leaf-cluster backend-service labels.
- Stress resource loading with the production-like number of channels and targets.
Validation matrix
| Area |
Minimum regression case |
| Core TLS |
Connect through each deployed TLS policy and intermediary |
| Go HTTP/2 |
Send legitimate and excessive non-DATA, non-HEADERS frames |
| Go RBAC |
Exercise matching and non-matching DENY rules, header canonicalization, and rejected names |
| Python aborts |
Await a status abort through the stock and any custom context |
| Python interceptors |
Raise from each custom interceptor shape in use |
| Python dependencies |
Resolve both the main protobuf path and grpc-status backport path |
| Java transport |
Open streams before and after SETTINGS_ACK and confirm the client-initiated limit |
| Java targets |
Parse representative custom schemes, authorities, escapes, and paths |
| Java resolvers |
Construct channels with global and explicit registries |
| Java xDS |
Load many targets while observing resource and stream progress |
| Java metrics |
Confirm LRS selection and leaf-cluster label dimensions |
| Java child channels |
Confirm injected interceptors or credentials on dynamic children |
Load only the indexed reference relevant to the implementation and task, then
retain its implementation-specific checks in code review and regression tests.
1---2name: grpc-knowledge-patch3description: gRPC4license: MIT5---678# gRPC Knowledge Patch910Apply this skill when changing gRPC transports, generated tooling, Python11servers, Go authorization, Java channels, xDS, or load-balancing behavior.1213## Working method14151. Identify the implementation, package versions, transport, and deployment16 platform involved in the task.172. Read the matching reference before relying on a default, dependency bound,18 xDS matcher, server limit, or dynamically created channel.193. Treat security-related defaults as behavior changes even when application20 code did not opt in explicitly.214. Preserve intentional compatibility overrides until integration and22 interoperability tests show they are no longer needed.235. Test both success and failure paths for interceptors, name resolution,24 authorization, connection setup, and control-plane resource loading.256. Prefer the project's manifests, lockfiles, code, and observed runtime26 behavior when they conflict with assumptions outside this patch.2728## Reference index2930| Reference | Topics |31| --- | --- |32| [transport-security-and-tooling.md](references/transport-security-and-tooling.md) | Post-quantum TLS, HTTP/2 frame-flood and stream limits, Android server TLS 1.3, Linux ARM64 `Grpc.Tools` packaging |33| [python-apis-runtime-and-dependencies.md](references/python-apis-runtime-and-dependencies.md) | Async status aborts, custom interceptor failures, protobuf bounds, Python 3.15 |34| [authorization-and-xds.md](references/authorization-and-xds.md) | Go RBAC matchers and header validation, deprecated `source_ip`, ORCA-to-LRS propagation, aggregate-cluster labels, control-plane connections |35| [java-channel-and-configuration.md](references/java-channel-and-configuration.md) | RFC 3986 parsing, per-channel resolver registries, numeric service config, child-channel configuration |3637## Breaking changes, defaults, and compatibility risks3839### TLS negotiation changes without an opt-in4041- Expect new gRPC Core TLS connections to use post-quantum cryptography in key42 exchange by default.43- Recheck TLS inspection, policy enforcement, interoperability, and latency44 assumptions when transport behavior changes despite unchanged application45 configuration.46- On Android, account for TLS 1.3 on OkHttp-based gRPC Java servers as well as47 clients. Do not retain a server-only assumption that TLS 1.3 is unavailable.48- Read [transport security and tooling](references/transport-security-and-tooling.md)49 before changing TLS policy or transport dependencies.5051### Java URI parsing now follows RFC 3986 by default5253- Re-test targets containing reserved characters, percent escapes, unusual54 authorities, or path-like components.55- Do not assume parser behavior remains legacy-compatible merely because no56 parsing option was enabled by the application.57- Keep target parsing tests close to custom resolvers and channel construction.5859### gRPC-Go throttles HTTP/2 control-frame floods6061- Expect a server to stop reading from a connection after the control-buffer62 throttle reaches its limit.63- The default threshold is 100 frames; DATA and HEADERS frames do not count64 toward it.65- Override the threshold only through66 `GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT`, and validate the chosen67 value under legitimate high-control-frame workloads as well as abusive ones.6869```sh70export GRPC_GO_EXPERIMENTAL_CONTROL_BUFFER_THROTTLE_LIMIT=20071```7273### Java Netty servers enforce stream limits during setup7475- Expect the client-initiated stream limit to apply proactively from connection76 startup rather than only after `SETTINGS_ACK`.77- Re-test clients that open streams aggressively during connection setup; the78 earlier timing window no longer permits them to bypass the configured limit.79- Include pre- and post-acknowledgment cases in transport-limit regression tests.8081### xDS DENY rules enforce more matchers and validate header names8283- Treat `Metadata` and `RequestedServerName` as enforced gRPC-Go xDS RBAC84 permission fields. The prior ignored behavior could let DENY rules fail open.85- Expect nested `Principal` and `Permission` header matchers, including86 non-lowercase names, to be validated and canonicalized.87- Reject `:scheme` and `grpc-`-prefixed matchers, and treat `host` as88 `:authority`.89- Re-test mixed-case names that previously matched nothing and could let a DENY90 rule fail open.91- Continue accepting deprecated `source_ip` principals as equivalent to92 `direct_remote_ip`, but generate the current spelling in new configuration.9394### Java xDS control-plane connections are channel-scoped again9596- Do not assume xDS control-plane connections are reused across channels.97- Reuse across many targets could exhaust the control plane's98 `MAX_CONCURRENT_STREAMS`, leaving new channels stuck in name resolution while99 waiting for resources.100- Capacity-test many-channel deployments and diagnose stalled resolution with101 both channel state and control-plane stream limits in view.102103### Python protobuf compatibility has two distinct paths104105- Treat 7.35.1 as the lower bound for the main Python protobuf dependency.106- Do not apply that bound indiscriminately to the separate v1.83.x107 `grpc-status` backport, whose relaxed constraint retains protobuf 6.x108 compatibility.109- Resolve the package actually constraining protobuf before changing a lockfile.110111### Aggregate-cluster metric labels identify the leaf112113- Expect gRPC Java xDS metrics for aggregate clusters to use the leaf cluster114 name as the backend-service label.115- Update dashboards, alerts, joins, and cardinality expectations that grouped116 these metrics by the aggregate cluster name.117118## New APIs and capability quick reference119120### Abort async Python RPCs with a status object121122Use the status-based abort method directly from `grpc.aio.ServicerContext`:123124```python125async def handle(request, context):126 await context.abort_with_status(status)127```128129The method is part of the abstract async context interface. Keep custom context130implementations compatible with that interface, and test that control flow ends131as expected after the awaited abort.132133### Isolate Java name resolution per channel134135Use the `Grpc.newChannelBuilder` overload that accepts a136`NameResolverRegistry` when a channel must not depend on the process-global137registry. This supports isolated tests, embedded runtimes, and applications138whose channels require different resolver sets.139140### Customize dynamically created Java child channels141142Use `ChildChannelConfigurer` to intercept child channels created by load143balancers. Apply channel-specific interceptors or credential changes there144instead of assuming top-level channel customization reaches every dynamic child.145146### Accept ordinary Java numeric service-config values147148Pass integer-looking values such as `maxAttempts: 4` and149`backoffMultiplier: 2` to `defaultServiceConfig()` without converting them to150decimal literals first. Validation accepts any `Number` and normalizes accepted151values to `Double`.152153### Select ORCA metrics for LRS propagation154155Expect ORCA-to-LRS propagation to be enabled by default in gRPC Java. Under156gRFC A85, use xDS configuration to select which fields from backend ORCA metric157reports are copied into LRS load reports.158159### Use current Python and Linux ARM64 support160161- Include Python 3.15 in supported-runtime testing where the application adopts162 that interpreter.163- On Linux ARM64, account for the `Grpc.Tools` move to `manylinux_2_28` and the164 maximum-page-size alignment fix for its bundled `protoc` executable.165- Re-evaluate base-image compatibility when upgrading build tooling, even when166 generated source is unchanged.167168## Implementation checklists169170### Transport and packaging171172- Read [transport-security-and-tooling.md](references/transport-security-and-tooling.md).173- Exercise TLS handshakes against every relevant peer and middlebox.174- Load-test the HTTP/2 control-frame threshold before overriding it.175- Test the Java Netty stream limit during connection startup.176- Run the packaged `protoc` on the actual Linux ARM64 build image.177- Verify Android server and client TLS expectations separately.178179### Python180181- Read [python-apis-runtime-and-dependencies.md](references/python-apis-runtime-and-dependencies.md).182- Inspect both the gRPC and `grpc-status` dependency paths before resolving183 protobuf constraints.184- Await status-based aborts and update custom async contexts.185- Test interceptor exceptions for every unary and streaming call shape in use.186- Add Python 3.15 to CI only after native and generated dependencies agree.187188### Go authorization and server protection189190- Read [authorization-and-xds.md](references/authorization-and-xds.md) and the191 Go section of [transport-security-and-tooling.md](references/transport-security-and-tooling.md).192- Re-run DENY-policy tests for metadata, requested server names, nested headers,193 case normalization, reserved prefixes, and `host` mapping.194- Accept legacy `source_ip` input while emitting `direct_remote_ip` in new xDS195 configuration.196- Observe connection behavior at the default flood threshold before tuning it.197198### Java channels, xDS, and load balancing199200- Read [java-channel-and-configuration.md](references/java-channel-and-configuration.md)201 for channel construction and parsing.202- Read [authorization-and-xds.md](references/authorization-and-xds.md) for xDS203 telemetry, labels, and control-plane connection behavior.204- Test custom target strings under RFC 3986 parsing.205- Supply a channel-local resolver registry where global state is inappropriate.206- Verify child-channel interceptors and credentials on dynamic children.207- Update metric queries to use leaf-cluster backend-service labels.208- Stress resource loading with the production-like number of channels and targets.209210## Validation matrix211212| Area | Minimum regression case |213| --- | --- |214| Core TLS | Connect through each deployed TLS policy and intermediary |215| Go HTTP/2 | Send legitimate and excessive non-DATA, non-HEADERS frames |216| Go RBAC | Exercise matching and non-matching DENY rules, header canonicalization, and rejected names |217| Python aborts | Await a status abort through the stock and any custom context |218| Python interceptors | Raise from each custom interceptor shape in use |219| Python dependencies | Resolve both the main protobuf path and `grpc-status` backport path |220| Java transport | Open streams before and after `SETTINGS_ACK` and confirm the client-initiated limit |221| Java targets | Parse representative custom schemes, authorities, escapes, and paths |222| Java resolvers | Construct channels with global and explicit registries |223| Java xDS | Load many targets while observing resource and stream progress |224| Java metrics | Confirm LRS selection and leaf-cluster label dimensions |225| Java child channels | Confirm injected interceptors or credentials on dynamic children |226227Load only the indexed reference relevant to the implementation and task, then228retain its implementation-specific checks in code review and regression tests.