Fix for "Certificate has expired" error with Joplin Cloud and self-hosted sync targets

I am having issues with Nextcloud sync. I self-host the nextcloud and it shows a valid cert when I check from the web interface.

This worked for Joplin Cloud, and the same method could be applied on your server probably:

[Bug]: Let's Encrypt root CA isn't working properly · Issue #31212 · electron/electron · GitHub

1 Like

The workaround works, but does it present a security issue? Thank you.

No it doesn't, it's still a valid certificate.

1 Like

Thank you, thank you!!! Invaluable help. I was tearing my hair out with Joplin desktop having the certificate error and I kept thinking it was the cert on my nextcloud.

For those running their own Joplin Server using apache and certbot to manage the certificate generation, the following fixes the issue:

sudo certbot certonly --preferred-chain "ISRG Root X1" --apache

(Note this is a suggested reply in the link posted above by @laurent)

The joplin server setup I'm using is is based off of this thread Guide for Joplin-Server on Raspberry Pi (thanks to @MrKanister)

1 Like

In case others are having issues with --preferred-chain not being a recognized flag on Ubuntu 18.04 LTS, following this comment worked for me: [Bug]: Let's Encrypt root CA isn't working properly · Issue #31212 · electron/electron · GitHub

Thanks laurent! This fixed my desktop issue on desktop.

The option is called "Ignore TLS certificate errors".
So, now anyone could self-sign a certificate for your synchronization target and pretend to be them. How is that not a security issue?

There is another option, "Custom TLS certificates", isn't it better to download the certificate of your sync target and import it here?

1 Like

It is. This is a temporary, stopgap solution.

1 Like

If anyone uses an automated update service (like /usr/bin/certbot renew) and wants to apply the option for preferred chain only to a particular domain, then the right place is in the config file at /etc/letsencrypt/renewal/your.domain.name.conf with this syntax:

... cut on purpose

[renewalparams]
account = ...obfuscated...
authenticator = webroot
preferred_chain = ISRG Root X1
webroot_path = /...obfuscated...,
server = https://acme-v02.api.letsencrypt.org/directory

... cut on purpose

And the renewal be forced with /usr/bin/certbot renew --force-renewal.

1 Like

Yes as mentioned it was just a workaround and it is indeed not secure. Thanks for the reminder anyway - I've updated the top post with more info about it.

unfortunately, adding a line did not help
preferred_chain = ISRG Root X1

letsencrypt certificate has been refreshed as you can see by date, but joplin desktop still won't sync with error.

Only Ignore TLS certificate errors helps :frowning:

I've resolved the issue on my self-hosted Joplin cloud. The "preferred chain" solution does actually work, however simply telling certbot/traefik/whatever where to get new certificates doesn't cause it to replace old ones, so you actually need to delete your certificate store to have them get refreshed.

To verify that you're seeing the "correct" error, run a command like this one:

$ openssl s_client -connect joplin.example.com:443 -servername joplin.example.com
CONNECTED(00000005)
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=1 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
depth=3 O = Digital Signature Trust Co., CN = DST Root CA X3
verify error:num=10:certificate has expired
notAfter=Sep 30 14:01:15 2021 GMT
verify return:0
---
Certificate chain
 0 s:/CN=joplin.example.com
   i:/C=US/O=Let's Encrypt/CN=R3
 1 s:/C=US/O=Let's Encrypt/CN=R3
   i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
 2 s:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
# Lines omitted...

    Start Time: 1633452339
    Timeout   : 7200 (sec)
    Verify return code: 10 (certificate has expired)
---
^C

Note that you see "certificate has expired" as the error message, note that "ISRG Root X1" is listed as a signer but so is "DST Root CA X3". The DST certificate is the expired one.

Steps to resolve

  1. Update your preferred chain to "ISRG Root X1".
  2. Delete the currently-valid certificate.
  3. Restart your services.

I use traefik, so the following config snippet suits step 1:

[certificatesResolvers.le.acme]
preferredChain = "ISRG Root X1"

To accomplish step 2 using my setup, I deleted the configured acme.json file (certificatesResolvers.le.acme.storage file).

To confirm that everything is working, rerun the same command from before and see the new output:

$ openssl s_client -connect joplin.example.com:443 -servername joplin.example.com
CONNECTED(00000005)
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = joplin.example.com
verify return:1
---
Certificate chain
 0 s:/CN=joplin.example.com
   i:/C=US/O=Let's Encrypt/CN=R3
 1 s:/C=US/O=Let's Encrypt/CN=R3
   i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1
---
# Lines omitted...

    Start Time: 1633453694
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
^C

I ran these tests using LibreSSL 2.6.5.

sorry I am a bit late but I have alse experienced the certificate error. I self host with nextcloud.

It appears that this error only affects the windows client. Both the android and linux (manjaro in my case) clients work without the Ignore TLS Certificate errors in the settings.

I'm afraid the Windows client only assertion isn't the case @luciandf. I have experienced the issue using the AppImage on Debian Linux Buster, with self-host Nextcloud secured with LetsEncrypt.

yes sorry I meant to get back to my post. When I tried on my linux machine, the client I was using wasn't updated at the latest version! After the update to the latest version I got the error too!

1 Like

Maybe it's true, but it doesn't work for me. I updated the letsencrypt certificate for Nextcloud a few days ago. I have the status

  Start Time: 1633547635
     Timeout: 7200 (sec)
     Verify return code: 0 (ok)
     Extended master secret: no
     Max Early Date: 0

and the desktop client still shows me sync errors

EDIT. the joplin mobile app syncs without any problem

after many attempts on the server it turned out that it is enough to install the new version of joplin 2.5.1
The only question is whether the joplin itself changes something or it was enough to do a reinstall.

It is Electron that was the issue. 2.5 upgraded the framework.