Virtualmin SSL Not Working? Why Your Site Stays on HTTP
Virtualmin SSL not working and your site still on HTTP? See the checks I used to spot a self-signed cert and switch to Let's Encrypt.

If your Virtualmin SSL is not working and the site still loads on plain http://, the certificate in the panel is most likely a self-signed placeholder. Browsers don't trust it, and Virtualmin won't send visitors to HTTPS until you tell it to. The fix is to replace it with a free Let's Encrypt certificate, then turn on the HTTPS redirect.
This guide explains why it happens, how to read the clues on the SSL Certificate page, and the exact order of steps that gets the padlock showing.
Why is my Virtualmin site still on HTTP when it has SSL?
"Has SSL" and "serves trusted HTTPS" are two different things. A site needs three things before visitors see the padlock:
- An HTTPS website (Apache listening on port 443) for the domain.
- A certificate that browsers trust, issued by a real certificate authority.
- A redirect that sends every http:// request to https://.
When Virtualmin creates a new virtual server, it usually handles the first item and fills the second with a self-signed certificate. However, it doesn't do the third. So the site keeps answering on HTTP. Anyone who types https:// gets a security warning instead of a padlock. From the outside, that looks exactly like broken SSL, even though the panel shows a certificate with years left on it.
To fix it, you replace the placeholder with a Let's Encrypt certificate and switch on the redirect. Both take a few clicks in the panel, and the full steps are below.
How to read the SSL Certificate page
Open Server Configuration → SSL Certificate for the domain. At first glance, the page often looks reassuring. A typical default certificate shows RSA keys, an expiry date about five years away, and a long countdown of days until it runs out.
That long expiry is the first clue. Trusted public certificates last months, not five years. Three other lines usually confirm the problem:
- Certificate type: Self-signed. The server signed the certificate itself, and no browser trusts that.
- Other domain names: localhost, fqdn.example.com, fqdn. These are leftovers from the default certificate Virtualmin generates. Nobody chose them, and they will never match a real visitor's address bar.
- Used by services: Webmin, Usermin, Dovecot, Postfix. Apache isn't on this list, which makes it easy to assume the website isn't using the certificate at all.
That last point misleads a lot of people, so it's worth a closer look.
Why there's no SSL checkbox on the domain
Because Apache is missing from "Used by services", the natural next move is to open Edit Virtual Server → Enabled features and look for an "SSL website" option. On current versions, the list shows items such as DNS for domain, Apache website, MariaDB database and Mail for domain. There's no SSL option to tick.
The next guess is usually that SSL is switched off for the whole server. You can check this under System Settings → Features and Plugins. On a standard setup, Apache SSL website is already enabled there, set as a default, and in use by every domain on the server.
In recent Virtualmin releases, the SSL website comes bundled with the Apache website feature. That's why it doesn't appear as its own checkbox on the domain's features page. The HTTPS site already exists, and it's simply serving the self-signed certificate. Also, the "Used by services" line covers Webmin, mail and similar services, not Apache.
So the real problem is rarely a missing feature. It's an untrusted certificate plus a missing redirect.
How to fix Virtualmin SSL not working in 5 steps
Follow these steps in order, because the certificate request in step 3 fails if steps 1 and 2 aren't right.
1. Confirm the SSL website feature is on
Open System Settings → Features and Plugins and check that Apache SSL website is ticked. Look at the Domains column too. If it matches the Apache website count, every site already has HTTPS. You can move on. If the feature is off, tick it, save, and then enable it for the domain.
2. Check DNS and Cloudflare before you request anything
Let's Encrypt checks that you control the domain by loading a file from your server over HTTP. That only works if the domain's A record points at your server's IP address. If the domain sits behind Cloudflare with the orange cloud on, switch it to DNS only (grey cloud) while you request the certificate. Once it's issued, turn the proxy back on and set Cloudflare's SSL mode to Full (strict), which needs exactly this kind of valid certificate on your server.
3. Request a Let's Encrypt certificate for the real hostname only
On the SSL Certificate page, open the SSL Providers tab and choose Let's Encrypt. Enter only the real hostname, such as the domain or subdomain itself. Leave out any wildcard (*.) entry and the leftover localhost and fqdn.example.com names. Let's Encrypt's standard HTTP check can't issue wildcard certificates, and it can't verify names that aren't real public domains. If you include them, the whole request fails. Then click Request Certificate.
4. Turn on the HTTP to HTTPS redirect
A valid certificate doesn't move anyone to HTTPS by itself. In the domain's Web Configuration → Website Options, set "Redirect all requests to SSL site" to Yes and save. After that, every http:// request goes to the https:// version.
5. Check the firewall and the site's own URLs
Make sure port 443 (the https service) is allowed in the server firewall. If the site runs WordPress, update both addresses in Settings → General to https://. Then run a search-and-replace on the old http:// links. Otherwise, visitors may see mixed-content warnings and images that won't load.
To confirm the fix, open the http:// address in a private window. It should jump to https:// and show a padlock with no warning.
Quick decision rule: what the SSL page means
When Virtualmin SSL is not working and the panel says one thing while the browser says another, use this table to decide what to do next.
| What the panel shows | What it means | What to do |
|---|---|---|
| Certificate type: Self-signed | Browsers will warn visitors | Request Let's Encrypt via SSL Providers |
| Expiry years away | Almost certainly the default placeholder | Treat it as self-signed and replace it |
| Names like localhost or fqdn.example.com | Leftovers from the default certificate | Leave them out of the new request |
| Wildcard (*.) in the name list | Needs DNS validation, not HTTP | Request the plain hostname only |
| No SSL checkbox on the domain | SSL is bundled with Apache website | Check System Settings → Features and Plugins |
| Valid certificate but site still on HTTP | No redirect yet | Turn on "Redirect all requests to SSL site" |
Common mistakes to avoid
The most common mistake is reading "Used by services" as a full list of everything that uses the certificate. It isn't. Taking it at face value sends people hunting for a missing feature. They check the domain first, then the server. Meanwhile, the real issue sits in plain sight: the certificate type says Self-signed.
A faster approach is to check two lines first: certificate type and expiry date. If the type is self-signed or the expiry is years away, go straight to Let's Encrypt and the redirect. It also helps to open the https:// address in a browser before changing any settings. A warning page there proves the HTTPS site already exists. That rules out the feature hunt straight away.
Other mistakes worth avoiding:
- Requesting a certificate while Cloudflare's proxy is on, which can block the HTTP check.
- Keeping the wildcard or leftover names in the request, which makes it fail.
- Forgetting the redirect, so the site works on HTTPS but visitors still land on HTTP.
Self-signed certificates on the admin panel itself are one of the gaps covered in this VPS security audit guide. This is the same problem, only on a live website instead of the panel. Using Cloudflare? The guide to WordPress security basics with Cloudflare explains why the SSL mode on that side matters too.
Key takeaways
- A certificate in the panel doesn't mean trusted HTTPS, so check the certificate type first.
- An expiry date years away almost always means a self-signed placeholder.
- In current Virtualmin releases, the SSL website comes with the Apache website feature, so don't hunt for a separate checkbox.
- Request Let's Encrypt for the real hostname only, with no wildcard and no leftover names.
- Turn on the HTTPS redirect, or visitors will keep landing on HTTP.
If you'd rather not dig through server panels yourself, SSL, DNS and Cloudflare setup is part of my WordPress maintenance and security service. Get in touch and describe what your site is doing.