# Free SSL Checker: Test Certificate Expiry & Issuer

> Source: https://hostinginfos.com/ssl-checker/  
> Last updated: 2026-10-18

SSL Checker Tool 

Check any website’s SSL certificate, issuer and expiry date in seconds. Spot expired or misconfigured certificates before your visitors do.

   

## SSL Checker

 

Enter a domain to see its certificate details, validity period, covered domains and more.

     

   

## What This Tool Checks

 

A quick look at the details shown in your SSL report.

  **Expiry Date** When the certificate stops being valid and how many days are left before browsers show a warning. **Issuer** The certificate authority (CA) that signed the certificate, such as Let’s Encrypt, Google Trust Services or DigiCert. **Hostname Match** Whether the certificate actually covers the domain you entered, including wildcard names. **Covered Domains (SAN)** Every domain and subdomain the certificate is valid for. **Browser Trust** Whether a secure HTTPS connection to the site can be completed without certificate errors. **Fingerprint & Serial** Unique identifiers for the certificate, useful for comparing or verifying installs. **CAA Records** DNS records that control which certificate authorities may issue certificates for the domain. **Validity Period** How long the certificate lasts in total. Modern public certificates are typically short-lived.    

## FAQs

 

Answers to the most common SSL questions. Still stuck? [Contact us](https://hostinginfos.com/contact-us/).

  What is an SSL certificate? 

An SSL/TLS certificate encrypts the connection between your website and its visitors, protecting sensitive data such as passwords and payment details. It also proves the site is really operated by the domain owner.

   How do I check my SSL certificate? 

Type your domain into the checker above and click “Check SSL”. You will see the issuer, validity dates, days remaining and the domains the certificate covers.

   Is this SSL checker free? 

Yes. The tool is completely free and needs no account or sign-up.

   Why does an SSL certificate matter? 

It keeps visitor data private, removes the “Not secure” browser warning, builds trust, and HTTPS is a lightweight ranking signal in Google Search.

   What happens when my SSL certificate expires? 

Browsers show a full-page security warning and many visitors will leave. Expired certificates can also break APIs, payment flows and hurt your SEO and conversions.

   How do I fix an expired SSL certificate? 

Renew or reinstall the certificate through your hosting provider or certificate authority. Many hosts issue and auto-renew free certificates through Let’s Encrypt, so check your control panel first.

   What does “hostname mismatch” mean? 

It means the certificate does not list the domain you checked. Common causes are a missing `www` or subdomain on the certificate, or the domain pointing to a server that has someone else’s certificate installed.

   How often should I check my SSL certificate? 

Check after any hosting or DNS change and at least once a month, or set up expiry monitoring. Aim to renew when 30 days or fewer remain.

   Can I check any website’s certificate? 

Yes. You can check the SSL certificate of any public website on port 443 by entering its domain name.

   Where does the certificate data come from? 

The tool connects to the domain on port 443 through a public certificate lookup service, then runs a separate in-browser HTTPS check and a Google Public DNS query for CAA records.

    

## Related Resources

 

Learn more about hosting, domains and choosing the right provider.

  [Guide  
 What Is Web Hosting? A Complete 2026 Guide  
 A plain-English guide to hosting types, renewal prices, uptime and choosing a host.  
 Read the guide →](https://hostinginfos.com/blog/what-is-web-hosting-a-complete-guide/)  
 [Hosting Control Panel  
 Best Hosting Control Panel in 2026: 12 Options Ranked  
 12 panels compared on licence costs, performance and security, with a migration checklist.  
 Compare panels →](https://hostinginfos.com/blog/best-hosting-control-panel/)  
 [Hosting Providers  
 Best Managed Hosting Provider in 2026  
 Verified pricing, real renewal costs and overage rates, with the right pick for your budget.  
 See the top picks →](https://hostinginfos.com/blog/best-managed-hosting-provider/)  
 [Hosting Providers  
 Best VPS Hosting Providers in 2026  
 Verified pricing, renewal costs and honest pros and cons for every budget and skill level.  
 See the top picks →](https://hostinginfos.com/blog/best-vps-hosting-providers/)    

## Need hosting with free SSL?

 

Read our independent hosting reviews and comparisons, with real pricing, renewal costs and honest drawbacks.

 

[Hosting Reviews](https://hostinginfos.com/blog/category/hosting-reviews/)  
 [Hosting Providers](https://hostinginfos.com/blog/category/hosting-providers/)

  

 

var root = document.getElementById('hi-ssl'); if (!root || root.getAttribute('data-ready')) { return; } root.setAttribute('data-ready', '1');

 

var CERT_API = 'https://networkcalc.com/api/security/certificate/'; var DNS_API = 'https://dns.google/resolve';

 

var form = root.querySelector('.hi-form'); var input = root.querySelector('#hi-domain'); var btn = root.querySelector('.hi-btn'); var statusBox = root.querySelector('.hi-status'); var results = root.querySelector('.hi-results'); var panel = root.querySelector('.hi-panel'); var meta = root.querySelector('.hi-meta'); var runId = 0;

 

function el(tag, cls, text) { var n = document.createElement(tag); if (cls) { n.className = cls; } if (text !== undefined && text !== null) { n.textContent = text; } return n; }

 

function normalize(v) { v = String(v || '').trim().toLowerCase(); v = v.replace(/^[a-z][a-z0-9+.\-]*:\/\//, ''); v = v.split(/[\/?#]/)[0]; v = v.replace(/^[^@]*@/, ''); v = v.replace(/:\d+$/, ''); v = v.replace(/\.+$/, ''); try { v = new URL('http://' + v).hostname; } catch (e) { /* keep as typed */ } return v; }

 

function validate(d) { if (!d) { return 'Please enter a domain name, for example example.com.'; } if (/^\d{1,3}(\.\d{1,3}){3}$/.test(d) || d.indexOf(':') !== -1) { return 'Please enter a domain name, not an IP address.'; } if (d.length > 253) { return 'That domain name is too long.'; } var labels = d.split('.'); if (labels.length < 2) { return 'Please enter a full domain name, for example example.com.'; } var ok = labels.every(function (l) { return /^[a-z0-9]([a-z0-9\-]{0,61}[a-z0-9])?$/.test(l); }); if (!ok || /^\d+$/.test(labels[labels.length - 1])) { return 'That does not look like a valid domain name.'; } return ''; } function setStatus(msg, kind) { statusBox.textContent = msg || ''; statusBox.className = 'hi-status' + (msg && kind ? ' is-' + kind : ''); } function setLoading(on) { btn.disabled = on; btn.classList.toggle('is-loading', on); btn.firstChild.nodeValue = on ? 'Checking' : 'Check SSL'; } function withTimeout(ms) { var ctrl = typeof AbortController !== 'undefined' ? new AbortController() : null; var timer = setTimeout(function () { if (ctrl) { ctrl.abort(); } }, ms); return { signal: ctrl ? ctrl.signal : undefined, clear: function () { clearTimeout(timer); } }; } /* ---------- data sources ---------- */ function getCert(domain) { var t = withTimeout(20000); return fetch(CERT_API + encodeURIComponent(domain), { signal: t.signal }) .then(function (r) { t.clear(); return r.json(); }) .then(function (j) { if (j && j.status === 'OK' && j.certificate) { return { cert: j.certificate }; } return { error: (j && (j.message || j.error)) || 'No certificate returned.' }; }) .catch(function (e) { t.clear(); return { error: 'network' }; }); } /* true = secure connection completed, false = failed (cert error or unreachable), null = timed out */ function probeHttps(domain) { var t = withTimeout(10000); return fetch('https://' + domain + '/', { mode: 'no-cors', cache: 'no-store', redirect: 'follow', signal: t.signal }) .then(function () { t.clear(); return true; }) .catch(function (e) { t.clear(); return (e && e.name === 'AbortError') ? null : false; }); } function getCAA(domain) { var t = withTimeout(8000); return fetch(DNS_API + '?name=' + encodeURIComponent(domain) + '&type=257', { headers: { accept: 'application/dns-json' }, signal: t.signal }) .then(function (r) { t.clear(); return r.json(); }) .then(function (j) { return (j.Answer || []).filter(function (a) { return a.type === 257; }).map(function (a) { var d = String(a.data || ''); var m = /^\\#\s+\d+\s+([0-9a-fA-F\s]+)$/.exec(d); if (m) { var hex = m[1].replace(/\s+/g, ''); var b = (hex.match(/../g) || []).map(function (h) { return parseInt(h, 16); }); var tl = b[1] || 0; return (b[0] || 0) + ' ' + String.fromCharCode.apply(null, b.slice(2, 2 + tl)) + ' "' + String.fromCharCode.apply(null, b.slice(2 + tl)) + '"'; } return d; }); }) .catch(function () { t.clear(); return null; }); } /* ---------- helpers ---------- */ function fmtDate(d) { return d.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); } function nameMatches(host, names) { return names.some(function (n) { n = n.toLowerCase(); if (n === host) { return true; } if (n.indexOf('*.') === 0) { var base = n.slice(1); return host.slice(-base.length) === base && host.split('.').length === n.split('.').length; } return false; }); } function copyBtn(text) { var cb = el('button', 'hi-copy', 'Copy'); cb.type = 'button'; cb.setAttribute('data-copy', text); return cb; } function row(label, value, opts) { opts = opts || {}; var tr = el('tr'); tr.appendChild(el('th', '', label)); var td = el('td'); if (opts.node) { td.appendChild(opts.node); } else if (opts.copy) { var box = el('div', 'hi-val'); box.appendChild(el('span', 'hi-mono', value)); box.appendChild(copyBtn(value)); td.appendChild(box); } else { td.textContent = value; } tr.appendChild(td); return tr; } function check(kind, title, text) { var c = el('div', 'hi-check is-' + kind); c.appendChild(el('i', '', kind === 'ok' ? '\u2713' : (kind === 'na' ? '?' : '!'))); var d = el('div'); d.appendChild(el('strong', '', title)); d.appendChild(el('span', '', text)); c.appendChild(d); return c; } /* ---------- rendering ---------- */ function renderSuccess(domain, cert, trusted, caa) { panel.textContent = ''; var from = new Date(cert.valid_from), to = new Date(cert.valid_to), now = new Date(); var days = Math.floor((to - now) / 86400000); var total = Math.max(1, to - from); var used = Math.min(100, Math.max(0, ((now - from) / total) * 100)); var names = (cert.alternate_names || []).map(function (n) { return String(n).replace(/^DNS:/i, ''); }); var match = names.length ? nameMatches(domain, names) : (String(cert.issued_to || '').toLowerCase() === domain); var expired = days < 0; var notYet = from > now;

 

var level = 'ok', label = 'Valid & Trusted'; if (expired) { level = 'err'; label = 'Certificate Expired'; } else if (notYet) { level = 'err'; label = 'Not Yet Valid'; } else if (!match) { level = 'err'; label = 'Hostname Mismatch'; } else if (trusted === false) { level = 'err'; label = 'Connection Not Trusted'; } else if (days <= 14) { level = 'err'; label = 'Expires Very Soon'; } else if (days <= 30) { level = 'warn'; label = 'Expiring Soon'; } /* summary */ var sum = el('div', 'hi-summary'); sum.appendChild(el('div', 'hi-icon is-' + level, level === 'ok' ? '\u2713' : '!')); var main = el('div', 'hi-sum-main'); main.appendChild(el('h3', '', domain)); main.appendChild(el('span', 'hi-pill is-' + level, label)); sum.appendChild(main); var dd = el('div', 'hi-days'); dd.appendChild(el('b', '', expired ? String(Math.abs(days)) : String(days))); dd.appendChild(el('span', '', expired ? 'days ago' : 'days left')); sum.appendChild(dd); panel.appendChild(sum); /* validity bar */ var bar = el('div', 'hi-bar is-' + level); var fill = el('i'); fill.style.width = used.toFixed(1) + '%'; bar.appendChild(fill); panel.appendChild(bar); var lbl = el('div', 'hi-barlbl'); lbl.appendChild(el('span', '', 'Issued ' + fmtDate(from))); lbl.appendChild(el('span', '', 'Expires ' + fmtDate(to))); panel.appendChild(lbl); /* checks */ var checks = el('div', 'hi-checks'); checks.appendChild(expired ? check('err', 'Expiry', 'Expired on ' + fmtDate(to) + '.') : notYet ? check('err', 'Expiry', 'Certificate is not valid until ' + fmtDate(from) + '.') : days <= 30 ? check(days <= 14 ? 'err' : 'warn', 'Expiry', 'Only ' + days + ' days remaining. Renew soon.') : check('ok', 'Expiry', days + ' days remaining.')); checks.appendChild(match ? check('ok', 'Hostname match', 'Certificate covers ' + domain + '.') : check('err', 'Hostname match', 'Certificate does not list ' + domain + '.')); checks.appendChild(trusted === true ? check('ok', 'Browser trust', 'A secure HTTPS connection was completed.') : trusted === false ? check('err', 'Browser trust', 'Browser could not complete a secure HTTPS connection.') : check('na', 'Browser trust', 'The HTTPS test timed out.')); var wild = names.some(function (n) { return n.indexOf('*.') === 0; }); checks.appendChild(check('ok', 'Certificate type', wild ? 'Wildcard certificate.' : 'Single / multi-domain certificate.')); panel.appendChild(checks); /* details table */ var sec = el('div', 'hi-section'); sec.appendChild(el('h3', '', 'Certificate Details')); var wrap = el('div', 'hi-scroll'); var table = el('table', 'hi-table'); var tb = el('tbody'); tb.appendChild(row('Issued To', cert.issued_to || '-')); tb.appendChild(row('Issued By', cert.issued_by || '-')); tb.appendChild(row('Valid From', fmtDate(from))); tb.appendChild(row('Valid Until', fmtDate(to))); tb.appendChild(row('Validity Period', Math.round(total / 86400000) + ' days')); if (cert.serial_number) { tb.appendChild(row('Serial Number', cert.serial_number, { copy: true })); } if (cert.fingerprint) { tb.appendChild(row('Fingerprint (SHA-1)', cert.fingerprint, { copy: true })); } table.appendChild(tb); wrap.appendChild(table); sec.appendChild(wrap); panel.appendChild(sec); /* SAN */ var sSec = el('div', 'hi-section'); var h = el('h3', '', 'Covered Domains (SAN)'); h.appendChild(el('span', 'hi-badge', names.length + (names.length === 1 ? ' name' : ' names'))); sSec.appendChild(h); if (names.length) { var tags = el('div', 'hi-tags'); names.slice(0, 40).forEach(function (n) { tags.appendChild(el('em', '', n)); }); if (names.length > 40) { tags.appendChild(el('em', 'is-more', '+ ' + (names.length - 40) + ' more')); } sSec.appendChild(tags); } else { sSec.appendChild(el('p', 'hi-empty', 'No alternative names listed on this certificate.')); } panel.appendChild(sSec);

 

/* CAA */ var cSec = el('div', 'hi-section'); var ch = el('h3', '', 'CAA Records'); ch.appendChild(el('span', 'hi-badge', caa ? caa.length + (caa.length === 1 ? ' record' : ' records') : 'unavailable')); cSec.appendChild(ch); if (caa && caa.length) { var ct = el('div', 'hi-tags'); caa.forEach(function (c) { ct.appendChild(el('em', '', c)); }); cSec.appendChild(ct); } else { cSec.appendChild(el('p', 'hi-empty', caa ? 'No CAA records found on ' + domain + '. Any certificate authority may issue certificates for this name.' : 'CAA records could not be retrieved.')); } panel.appendChild(cSec);

 

meta.textContent = 'Results for ' + domain + ' \u00b7 ' + new Date().toLocaleString(); results.hidden = false; }

 

function renderFailure(domain, trusted) { panel.textContent = ''; var sum = el('div', 'hi-summary'); sum.appendChild(el('div', 'hi-icon is-err', '!')); var main = el('div', 'hi-sum-main'); main.appendChild(el('h3', '', domain)); main.appendChild(el('span', 'hi-pill is-err', trusted === false ? 'No Valid SSL Found' : 'Certificate Not Retrieved')); sum.appendChild(main); panel.appendChild(sum);

 

var checks = el('div', 'hi-checks'); checks.appendChild(trusted === false ? check('err', 'Browser trust', 'A secure HTTPS connection could not be completed.') : check('na', 'Browser trust', 'Result inconclusive.')); panel.appendChild(checks);

 

panel.appendChild(el('p', 'hi-empty', 'We could not read a certificate for ' + domain + '. Common causes: no SSL certificate is installed, the certificate has expired, the domain does not point to a web server, or port 443 is blocked. Check the domain spelling, your DNS records and your hosting SSL settings, then try again.'));

 

meta.textContent = 'Checked ' + domain + ' \u00b7 ' + new Date().toLocaleString(); results.hidden = false; }

 

/* ---------- run ---------- */ function run(domain) { var id = ++runId; setLoading(true); setStatus('Checking the SSL certificate for ' + domain + '\u2026', 'info'); results.hidden = true;

 

Promise.all([getCert(domain), probeHttps(domain), getCAA(domain)]).then(function (r) { if (id !== runId) { return; } setLoading(false); var c = r[0], trusted = r[1], caa = r[2]; if (c.cert) { setStatus('', ''); renderSuccess(domain, c.cert, trusted, caa); } else if (c.error === 'network' && trusted === true) { setStatus('The HTTPS connection works, but the certificate lookup service could not be reached. Please try again in a moment.', 'error'); } else { setStatus('', ''); renderFailure(domain, trusted); } }); }

 

function submit() { var domain = normalize(input.value); var err = validate(domain); if (err) { results.hidden = true; setStatus(err, 'error'); input.focus(); return; } input.value = domain; run(domain); }

 

form.addEventListener('submit', function (e) { e.preventDefault(); submit(); });

 

panel.addEventListener('click', function (e) { var b = e.target.closest ? e.target.closest('.hi-copy') : null; if (!b) { return; } var text = b.getAttribute('data-copy') || ''; function done() { b.textContent = 'Copied'; b.classList.add('is-done'); setTimeout(function () { b.textContent = 'Copy'; b.classList.remove('is-done'); }, 1500); } if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(text).then(done, function () {}); } else { var ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); done(); } catch (x) { /* ignore */ } document.body.removeChild(ta); } }); })();
