grpc/grpc-java · error · IllegalStateException

A key manager is required

Error message

A key manager is required

What it means

TlsServerCredentials.Builder.build() requires some form of server-side private key material. If neither a certificate chain nor key managers were configured, the credentials would be unusable for TLS, so build() throws this IllegalStateException.

Source

Thrown at api/src/main/java/io/grpc/TlsServerCredentials.java:395

     * javax.net.ssl.X509TrustManager}.
     */
    public Builder trustManager(TrustManager... trustManagers) {
      List<TrustManager> trustManagerList = Collections.unmodifiableList(new ArrayList<>(
          Arrays.asList(trustManagers)));
      clearTrustManagers();
      this.trustManagers = trustManagerList;
      return this;
    }

    private void clearTrustManagers() {
      this.rootCertificates = null;
      this.trustManagers = null;
    }

    /** Construct the credentials. */
    public ServerCredentials build() {
      if (certificateChain == null && keyManagers == null) {
        throw new IllegalStateException("A key manager is required");
      }
      return new TlsServerCredentials(this);
    }
  }

  /** The level of authentication the server should expect from the client. */
  public enum ClientAuth {
    /** Clients will not present any identity. */
    NONE,

    /**
     * Clients are requested to present their identity, but clients without identities are
     * permitted.
     */
    OPTIONAL,

    /**
     * Clients are requested to present their identity, and are required to provide a valid

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Call keyManager(KeyManager...) or keyManager(String certChain, String privateKey) to supply the server identity
  2. Or call certificateChain(...) alongside a private key configuration
  3. If the endpoint should not be a TLS server, use InsecureServerCredentials or TlsChannelCredentials for clients instead

Example fix

// before
TlsServerCredentials.newBuilder()
    .trustManager(trustCerts) // only client-auth trust
    .build(); // throws
// after
TlsServerCredentials.newBuilder()
    .keyManager(serverCertChainPem, serverPrivateKeyPem)
    .trustManager(trustCerts)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (certChain == null && keyManagers == null) {
  throw new IllegalArgumentException("TLS server needs keyManager or certificateChain");
}

Try / catch

try {
  creds = tlsBuilder.build();
} catch (IllegalStateException e) {
  throw new ConfigException("TLS server credentials incomplete: provide keyManager", e);
}

Prevention

When it happens

Trigger: Building TlsServerCredentials without calling keyManager(...) and without certificateChain(...) — i.e. relying only on trustManagers (client auth settings) or no TLS material at all.

Common situations: Configuring mutual TLS and only setting trustManagers for client verification; forgetting that TLS servers always need their own identity; porting client-side (TlsChannelCredentials) code where key material is optional.

Related errors


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