Certificate upgrade Java Tomcat (and Apache)


Some side effects after renewal of my certficates (old fashion certbot v 0.28)

This used to work before renewal:
URL lockpngUrl;
try {
lockpngUrl = new URL(“https://” + pictureFile);
try {
iStream = lockpngUrl.openStream();
Now it throws Java Sun security exception.
Haven’t solved this issue for now.
For those who face this problem some help & explanation can be found here https://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore
Good luck


The stack trace itself and exact Java version would help us help you.

Older versions of Java are missing the DST Root CA X3 in their trust store, which is the root that the current Let’s Encrypt intermediates rely on (and has from day 1).



Here is the stack :


   at javax.imageio.spi.FilterIterator.next(ServiceRegistry.java:825)

   at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:528)

   at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:513)

   at org.apache.poi.ss.util.ImageUtils.getImageDimension(ImageUtils.java:76)

   at org.apache.poi.ss.util.ImageUtils.setPreferredSize(ImageUtils.java:146)

   at org.apache.poi.xssf.usermodel.XSSFPicture.getPreferredSize(XSSFPicture.java:221)

   at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:180)

   at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:155)

   at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:146)

   at ch.ubik.common.servlet.lbc.ExcelPageWriter.getPicture(ExcelPageWriter.java:758)

   at ch.ubik.carol.lbc.excel.SliceList.fillHeaderRow(SliceList.java:170)

   at ch.ubik.carol.lbc.excel.SliceList.fillSheet(SliceList.java:139)

   at ch.ubik.carol.lbc.excel.SliceList.<init>(SliceList.java:121)

   at ch.ubik.carol.lbc.admin.Slices.getExcelList(Slices.java:369)

   at ch.ubik.carol.srv.admin.SlicesSrv.getAdminExcelWriter(SlicesSrv.java:65)

   at ch.ubik.carol.srv.admin.AbstractAdminLoginSrv.getExcelWriter(AbstractAdminLoginSrv.java:179)

   at ch.ubik.carol.srv.AbstractCarolServlet.getExcelWriter(AbstractCarolServlet.java:416)

   at ch.ubik.carol.srv.AbstractCarolServlet.doService(AbstractCarolServlet.java:282)

   at ch.ubik.carol.srv.AbstractCarolServlet.doGet(AbstractCarolServlet.java:192)

   at ch.ubik.carol.srv.AbstractCarolServlet.doPost(AbstractCarolServlet.java:171)

   at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)

   at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)

   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

   at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)

   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)

   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)

   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)

   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)

   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)

   at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)

   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)

   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)

   at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)

   at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)

   at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)

   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)

   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)

   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

   at java.lang.Thread.run(Thread.java:722)

Java version is:

ava version “1.7.0_151”

OpenJDK Runtime Environment (IcedTea 2.6.11) (7u151-2.6.11-1~deb8u1)

OpenJDK 64-Bit Server VM (build 24.151-b01, mixed mode)



Hi _az,
I am still struglling with my certificate upgrade.

I am Debian Jessie.
My java version is “1.7.0_151”
OpenJDK Runtime Environment (IcedTea 2.6.11) (7u151-2.6.11-1~deb8u1)
OpenJDK 64-Bit Server VM (build 24.151-b01, mixed mode)
java full version is “1.7.0_151-b01”

On Let’s Encrypt Certificate Compatibility page
Java 7 >= 7u111 is noted as Known Compatible"

Does the build version (b01) plays a role ?

Following your advice I checked the content of my Java trust store with the command:
keytool -list -keystore cacerts
in /etc/ssl/certs/java
The output is in carets_debian.txt attached to this post.
However I am not able to figure out if I have there what is needed.

Could you please take a look and say if it is the case and if not what shall I do ?

Kind regards


Didn’t attach - try uploading it to https://dpaste.de .

Please also post your domain of pictureFile. There’s a variety of issues that could be occurring (e.g. you might not be sending any intermediate at all) and it’s impossible to identify otherwise.

The stack trace you posted appears to be unrelated to the HTTP call.


Thanks for your fedd back,
URL of the pictureFile is https://www.kreator.ch/carol/pix/lock.png
I tried dpaste and wonder if it worked …
Just in case another try with drag and drop to the post:
carets_debian.txt (28.5 KB)


Your trust store contains the required entry:

debian:dst_root_ca_x3.pem, Aug 19, 2017, trustedCertEntry,
Certificate fingerprint (SHA1): DA:C9:02:4F:54:D8:F6:DF:94:93:5F:B1:73:26:38:CA:6A:D7:7C:13

It seems like your program should work on OpenJDK 7. At least, a similar one does for me:

public class LetsEncryptTest {
  public static void main(String[] args) {
    try {
      final java.net.URL url = new java.net.URL("https://www.kreator.ch/carol/pix/lock.png");
      final java.util.Scanner sc = new java.util.Scanner(url.openStream());
    } catch(Exception e) {
$ sudo docker run --rm -it -v $(pwd):/java openjdk:7 java -version
java version "1.7.0_181"
OpenJDK Runtime Environment (IcedTea 2.6.14) (7u181-2.6.14-2~deb8u1)
OpenJDK 64-Bit Server VM (build 24.181-b01, mixed mode)
$ sudo docker run --rm -it -v $(pwd):/java openjdk:7 javac /java/LetsEncryptTest.java
$ sudo docker run --rm -it -v $(pwd):/java openjdk:7 java -cp /java/ LetsEncryptTest


Thanks a lot for your help.

It’s good to know that the required entry is in the trust store and thus I do not have to worry about my java installation. It is a great step forward and alleviation.:grin:

Now I will check what I screwed up in my program.
(I’ll be back tomorrow)


Hi _az,

I copied the test Class you wrote for me to my local (Windows 7, Eclipse) developpement environnement and tried to run it.
It crashes with the following stack:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1902)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1338)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1032)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1328)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1355)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:515)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1299)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at java.net.URL.openStream(URL.java:1037)
at ch.ubik.eksel.lbc.LetsEncryptTest.main(LetsEncryptTest.java:9)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:231)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1320)
… 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380)
… 19 more

Do I have some wrong set-up locally ?



Info: line 9 of the class in my source is:

final java.util.Scanner sc = new java.util.Scanner(url.openStream());


Wait, are you experiencing the problem on Linux or Windows? Your CA certificate list was from the Linux system, right?


You you hit the nail on the head. Sorry for my lack of competance.
I do develop and test on Windows (eclipse)
If the tests (on Windows) are ok then I compile and build (jar files) and deploy (copying the jar files) to production on Linux.
The crash occuring during tests on Windows I thought it would crash on Linux as well and that it had to do with java trust store on Linux.
That is where I was mistaking.
Because of the above mistake I sent you the carets content from Linux.
After your last reply I deployed on Linux my Windows crashing program and it works fine.
You taught me something, thanks a lot.
Provided I understood something I imagine that the certificate is missing in my Windows java certificates.
Would you be so kind to confirm it, and indicate how to make it work on Windows ?
Here is the CA certificate from my Windows system:
carets_win7.txt (11.5 KB)
I havent found any “dst_root_ca_x3” in it.
I suppose I have to insert it somehow to the carets …
If yes then what is the proper manner to do it ?

Kind regards and thanks again ?


I imagine the solution is for you to upgrade to Java 8 on Windows.

The problem is that Oracle are (or at least, at the time, were) responsible for distributing Java 7 on Windows. When Java 7 reached end-of-life in 2015, it looks like the DST Root CA X3 certificate had not yet been added to its root store. (But future OpenJDK/Linux releases did).

Since OpenJDK were, at that time, not creating packages for Windows, there is no edition of Java 7 you could install that would fix your problem.

Simple and correct solution - upgrade to Java 8 (or newer) on Windows and just tell Eclipse to compile down to Java 7 target.

You shouldn’t be running Java 7 anywhere anyway.

Complicated solution - use keytool to import the DST Root CA X3 to your Windows Java 7’s root store.


Hi _az,
Thanks for storical résumé and advice.
Unfortunately the correct solution (upgrade to Java 8) is for me, for the time being, not applicable. Main reason is that I do use applets which " Existing Applet support in Java SE 8 will continue through March 2019, after which it may be removed at any time." cf An Oracle White Paper, March 2018
So I am doomed to stay with java 7 and have to go for the complicated solution: keytool.
And, as you can imagine I come with a question about how to.
I have download my site (kreator.ch) cert using Chrome into cert_file.cer.
Seems to be the right one

Now I do not know how to import it to my trust store (on Windows)
I tried.

  1. To install it with right-click on the file. I did not have the chance to say in which cacerts I wanted it to be installed so it finished “somewhere”
  2. To add it with: keytool -import -alias ca -file cert_file.cer -keystore cacerts -storepass changeit
    Now I have a new entry in my cacerts:
    ca, 18 mars 2019, trustedCertEntry,
    Empreinte du certificat (SHA1) : 93:C5:7E:E0:75:E4:EE:0E:C4:F7:2B:FB:C2:79:8A:FC:36:1C:D2:87
    I am afraid that’s not it. My syntax must be wrong, probably “-alias ca”
    Could you give me the correct for the keytool -import command ?

Thanks in advance & regards.


You want to import DST Root CA X3, not your own certificate (or the intermediates).

I don’t know how to do it, your research is as good as mine. https://superuser.com/a/1092240 seems to provide an example for a Windows environment. Just make sure to import the right certificate, not the one written in the answer.

I’ve attached the DER-encoded DST Root CA X3 certificate for your convenience:

trustidrootx3_chain.der.txt (846 Bytes)


Hi _az,
Bingo !
I imported your .der file to my java jdk1.7.0_11 trust store and the problem is solved !
I can access files on https://www.kreator.ch from my Windows eclipse environment.
I hope that my tries to import my own certificate instead of the DST Root CA X3 will remain secret :stuck_out_tongue_winking_eye:
Just for my understanding: how did you generate trustidrootx3_chain.der file ?
I did some tries on my own to generate it via Chrome from https://letsencrypt.org/certificates/ and https://valid-isrgrootx1.letsencrypt.org/ and none of them worked.

Now, if you still support me, we could go to the main course.
My initial problem was, and still is, Problem updating ACME TLS-SNI-01 to alternative validation method
Despite the help of @rg305 we were not able to solve this issue. Beginning of February we had a tough and stressfull night (we were in my production environment !) trying to update but we failed. Fortunately @rg305 helped me to regenerate the “old fashion (certbot v 0.28)” certificates.
This certificate expires on May 2, 2019.
In order to avoid another nightmarish night like the one we had with Rudy, I decided not to try to fix this issue in production anymore.
I acquired another hosting and an another dns (kreator2.ch) and will reproduce a brave new environment for my web application.
I will try there to install Let’s Encrypt certificates with an alternative validation method.
For sure I will fail :tired_face:
Can I come back to you in a couple of days to take advantage of your experience in order to try to fix this issue ?

Thanks for your help so far and I hope you will not “let me down” :sunglasses:
Kind regards.