{"record":{"id":"3471437315e5daa1","repo":"grpc/grpc-java","slug":"a-key-manager-is-required","errorCode":null,"errorMessage":"A key manager is required","messagePattern":"A key manager is required","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/io/grpc/TlsServerCredentials.java","lineNumber":395,"sourceCode":"     * javax.net.ssl.X509TrustManager}.\n     */\n    public Builder trustManager(TrustManager... trustManagers) {\n      List<TrustManager> trustManagerList = Collections.unmodifiableList(new ArrayList<>(\n          Arrays.asList(trustManagers)));\n      clearTrustManagers();\n      this.trustManagers = trustManagerList;\n      return this;\n    }\n\n    private void clearTrustManagers() {\n      this.rootCertificates = null;\n      this.trustManagers = null;\n    }\n\n    /** Construct the credentials. */\n    public ServerCredentials build() {\n      if (certificateChain == null && keyManagers == null) {\n        throw new IllegalStateException(\"A key manager is required\");\n      }\n      return new TlsServerCredentials(this);\n    }\n  }\n\n  /** The level of authentication the server should expect from the client. */\n  public enum ClientAuth {\n    /** Clients will not present any identity. */\n    NONE,\n\n    /**\n     * Clients are requested to present their identity, but clients without identities are\n     * permitted.\n     */\n    OPTIONAL,\n\n    /**\n     * Clients are requested to present their identity, and are required to provide a valid","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/api/src/main/java/io/grpc/TlsServerCredentials.java#L377-L413","documentation":"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.","triggerScenarios":"Building TlsServerCredentials without calling keyManager(...) and without certificateChain(...) — i.e. relying only on trustManagers (client auth settings) or no TLS material at all.","commonSituations":"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.","solutions":["Call keyManager(KeyManager...) or keyManager(String certChain, String privateKey) to supply the server identity","Or call certificateChain(...) alongside a private key configuration","If the endpoint should not be a TLS server, use InsecureServerCredentials or TlsChannelCredentials for clients instead"],"exampleFix":"// before\nTlsServerCredentials.newBuilder()\n    .trustManager(trustCerts) // only client-auth trust\n    .build(); // throws\n// after\nTlsServerCredentials.newBuilder()\n    .keyManager(serverCertChainPem, serverPrivateKeyPem)\n    .trustManager(trustCerts)\n    .build();","handlingStrategy":"validation","validationCode":"if (certChain == null && keyManagers == null) {\n  throw new IllegalArgumentException(\"TLS server needs keyManager or certificateChain\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  creds = tlsBuilder.build();\n} catch (IllegalStateException e) {\n  throw new ConfigException(\"TLS server credentials incomplete: provide keyManager\", e);\n}","preventionTips":["Always configure keyManager for server TLS credentials","Distinguish server (needs identity) from client TLS builder usage in shared config code","Validate credential config files at startup, before building the server"],"tags":["grpc","tls","credentials","missing-config"],"backgroundTag":"missing-credentials","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}