I am trying to connect to gRPC server which has TLS enabled but doesn't require a client certificate. I have used many combinations using NettyChannelBuilder and ManagedChannelBuilder.
NettyChannelBuilder.forTarget("host:443")
.useTransportSecurity()
.keepAliveTime(30, TimeUnit.SECONDS)
.keepAliveTimeout(5, TimeUnit.SECONDS)
.negotiationType(NegotiationType.TLS)
.enableRetry()
.build();
Error is
io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
Underlying exception is
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
What am I doing wrong?
unable to find valid certification path to requested target
The server's certificate is not trusted. You should get a CA to issue a certificate for the server. If it is already a valid cert, make sure to provide the "certificate chain" when configuring the server, not just the bare server certificate.
If you didn't intend to use a typical "browser-trusted CA," you can sign the certificate with your own CA and use that CA's certificate as a trust source:
ChannelCredentials certs = TlsChannelCredentials.newBuilder()
// Could also be a server's self-signed cert
.trustManager(new File("path/to/ca.pem"))
.build();
NettyChannelBuilder.forTarget("host:443", certs)
.keepAliveTime(30, TimeUnit.SECONDS)
.keepAliveTimeout(5, TimeUnit.SECONDS)
.build();
There are many sites and scripts that describe how to make your own CA and sign server certificates, if that is what you end up wanting. For reference, this is the process for gRPC's tests.