I’m building a Node.js application to handle webhook requests from Telegram bots. The webhook registration works fine and Telegram confirms it’s set up correctly, but my server never receives any webhook updates.
I suspect the issue is related to SSL certificate configuration. My server uses Apache as a reverse proxy with self-signed certificates, but it seems like Telegram’s servers can’t properly validate the certificate chain.
Here’s my current Apache configuration:
<VirtualHost *:8443>
ServerName myserver.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.pem
SSLCertificateKeyFile /etc/ssl/private/server.key
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256
ProxyPass / http://localhost:4000/
ProxyPassReverse / http://localhost:4000/
</VirtualHost>
I generated the certificate using:
openssl req -newkey rsa:2048 -sha256 -nodes -keyout server.key -x509 -days 365 -out server.pem -subj "/C=GB/ST=London/L=London/O=My Company/CN=myserver.example.com"
Can someone explain how to properly configure the certificate chain so Telegram accepts the SSL connection? What specific Apache settings do I need for webhook delivery to work?
hey, i faced this too! self-signed certs won’t work with telegram unless you upload them. just get a free lets encrypt cert, it’s much easier and your bot will start receiving updates without any hassle!
Telegram’s webhook setup does not accept self-signed certificates by default because they lack a trusted signing authority. To resolve this, you can either upload your self-signed certificate when you call the setWebhook method, or you can obtain a free valid certificate from Let’s Encrypt, which is widely supported across hosting services. The latter option is generally simpler, as it eliminates the need for manual certificate uploads. I faced this issue previously, and switching to Let’s Encrypt was the most straightforward solution that allowed my bot to receive updates seamlessly.
Telegram needs either a legit certificate from a trusted CA or you have to upload your self-signed cert when setting the webhook. If you’re sticking with self-signed, use the certificate parameter when calling setWebhook to upload your cert file. Your OpenSSL command’s also missing the SAN extension - modern SSL won’t work without it. Add -addext "subjectAltName=DNS:myserver.example.com" to your cert generation command. I dealt with this same mess last year and honestly, self-signed certs are a pain to manage in production even when you get them working.