I have configured a tomcat application with SSL for client authentication purpose. It is on port 8443. It works fine so that when I try to hit tomcat with client certificate(client.p12) I got success and with another certificate which is not in the keystore gets bad ssl error. So this works.

Then I tried to put nginx in front of tomcat as a proxy but there I am always getting 502. Nginx is also on SSL. The below is the error I am getting.

2018/04/20 17:25:03 [error] 21884#0: *3 SSL_do_handshake() failed (SSL: error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate:SSL alert number 42) while SSL handshaking to upstream, client:, server:, request: "GET /print HTTP/1.1", upstream: "", host: ""

Can anybody help me to resolve this issue? Ultimately I just want to pass the tomcat certificate through nginx which is also on SSL. ( Nginx(https) -> Tomcat(https) ).

I know this is a strange requirement, but I need this.


  • 1
    Have a look at this: serverfault.com/questions/806141/… (not an exact duplicate, I presume) – Lenniey Apr 20 '18 at 12:39
  • 1
    Yeah. I have a client auth certificate for tomcat and I imported the same into the browser. But still I am getting same error on hitting Nginx. – Uvais Ibrahim Apr 20 '18 at 12:41
  • Could you post your nginx config? – Lenniey Apr 20 '18 at 13:23

From your comments, it sounds like you're using client-certificates for authentication. If so, you can't use the HTTP proxy from Nginx, and instead you have to use the Stream proxy. Check out the post here for more details:

How do I route HTTPS encrypted packets without decrypting it?

When dealing with client certificates, the client cert is effectively "consumed" during the TLS handshake process, so if Nginx is accepting the SSL connection first, the client will present the certificate to Nginx for validation. Since your tomcat application is expecting to handle the client-cert for authentication, the proxied connection doesn't have one to use; this would cause a TLS Handshake failure.

Using the Nginx Stream module would allow you to send the traffic without interruption (thereby preserving the client-certificate) to the tomcat process and allow proper authentication from the client-certificate.

It sounds like you only have one process to work with, so you won't need the SSL pre-read module (unless load balancing is required), you would probably just need the following:

stream {
    server {
        listen 443;
        listen [::]:443;

  • Hi Andrew, I tested this and it is working. Thanks. But, As I mentioned in question, nginx is the frontend and tomcat is the backend and hence I need to add a server_name in nginx which stream doesn't support. Can you tell me how I can rectify this ? – Uvais Ibrahim Apr 20 '18 at 14:37
  • server_name is only used if you're doing virtual hosting on the HTTP server, which you are not doing with the stream directive. Using stream basically turns off web hosting, and turn on TCP load balancing. With this configuration ALL traffic to 443 will be proxied to – Andrew Apr 20 '18 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.