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

  1. Use only NegotiationType.PLAINTEXT, PLAINTEXT_UPGRADE, or TLS when calling negotiationType().
  2. Align grpc-netty and grpc-core/grpc-api versions (use grpc-bom) so enum constants match.
  3. If TLS is intended, call negotiationType(NegotiationType.TLS) or use the shorthand usePlaintext()/useTransportSecurity().
  4. 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

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


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/5c5056a30ea8d21b. Report an issue: GitHub.