grpc/grpc-java · error · IllegalArgumentException
Unsupported negotiationType: ${negotiationType}
Error message
Unsupported negotiationType: ${negotiationType} What it means
createProtocolNegotiatorByType() switches over the configured NegotiationType (PLAINTEXT, PLAINTEXT_UPGRADE, TLS). If negotiationType holds a value outside the known enum cases, the default branch throws IllegalArgumentException("Unsupported negotiationType: ..."). This guards against unknown or corrupted enum values reaching negotiator creation.
Source
Thrown at netty/src/main/java/io/grpc/netty/NettyChannelBuilder.java:712
int getDefaultPort() {
return protocolNegotiatorFactory.getDefaultPort();
}
@VisibleForTesting
static ProtocolNegotiator createProtocolNegotiatorByType(
NegotiationType negotiationType,
SslContext sslContext,
ObjectPool<? extends Executor> executorPool) {
switch (negotiationType) {
case PLAINTEXT:
return ProtocolNegotiators.plaintext();
case PLAINTEXT_UPGRADE:
return ProtocolNegotiators.plaintextUpgrade();
case TLS:
return ProtocolNegotiators.tls(sslContext, executorPool, Optional.absent(), null, null);
default:
throw new IllegalArgumentException("Unsupported negotiationType: " + negotiationType);
}
}
@CanIgnoreReturnValue
NettyChannelBuilder disableCheckAuthority() {
this.managedChannelImplBuilder.disableCheckAuthority();
return this;
}
@CanIgnoreReturnValue
NettyChannelBuilder enableCheckAuthority() {
this.managedChannelImplBuilder.enableCheckAuthority();
return this;
}
void protocolNegotiatorFactory(ProtocolNegotiator.ClientFactory protocolNegotiatorFactory) {
checkState(!freezeProtocolNegotiatorFactory,
"Cannot change security when using ChannelCredentials");View on GitHub (pinned to 64daddc1f3)
Solutions
- Use only NegotiationType.PLAINTEXT, PLAINTEXT_UPGRADE, or TLS when calling negotiationType().
- Align grpc-netty and grpc-core/grpc-api versions (use grpc-bom) so enum constants match.
- If TLS is intended, call negotiationType(NegotiationType.TLS) or use the shorthand usePlaintext()/useTransportSecurity().
- Rebuild your code against the same grpc version as the runtime dependency.
Example fix
// before
builder.negotiationType(myNegotiationType); // may hold an unhandled value
// after
if (useTls) {
builder.negotiationType(NegotiationType.TLS);
} else {
builder.usePlaintext();
} Defensive patterns
Strategy: validation
Validate before calling
if (type != NegotiationType.PLAINTEXT && type != NegotiationType.PLAINTEXT_UPGRADE && type != NegotiationType.TLS) {
throw new IllegalStateException("NegotiationType not supported by NettyChannelBuilder: " + type);
} Type guard
static boolean isSupportedNegotiationType(NegotiationType t) {
return t == NegotiationType.PLAINTEXT || t == NegotiationType.PLAINTEXT_UPGRADE || t == NegotiationType.TLS;
} Try / catch
try {
channel.build();
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported negotiationType")) {
builder.usePlaintext(); // safe default
}
} Prevention
- Pin grpc-netty, grpc-core, grpc-api to one version via grpc-bom
- Prefer builder.usePlaintext()/useTransportSecurity() shorthands over raw enum assignment
- Recompile against the runtime grpc version after upgrades
When it happens
Trigger: Calling negotiationType(NegotiationType.X) with an enum constant not handled by the switch (e.g. a NegotiationType from a newer/older grpc version that this switch does not cover), or an internal call path supplying a null/foreign enum value.
Common situations: Version skew where code compiled against a newer grpc-core NegotiationType runs against an older grpc-netty; reflection or deserialization producing an unexpected enum value; custom subclasses of the builder overriding negotiationType handling.
Related errors
- No ALTS context information found
- Can't set TLS settings for ALTS
- Not implemented
- Not implemented
- Not implemented
AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08).
Data as JSON: /api/errors/5c5056a30ea8d21b.
Report an issue: GitHub.