Thanks Jay and Simon, my issue is resolved.
At the end of the day I found that it’s cloudflare’s certificate to blame. Switching to DNS challenge via Let’s Encrypt works like a charm.
Now I have slightly more knowledge about how Discourse under the hood works. Cool!
–
Upd: BTW, is it possible to allow users to choose how the will generate their certificate in the setup process? For newcomers like me, we will have to actually read and find the logs to find that certificates lead to connection failure.