How to Configure Certificate Expiry Monitoring in Uptime Kuma
Configure certificate expiry monitoring in Uptime Kuma by setting global notification thresholds in Settings → Certificate Expiry, enabling the "Certificate Expiry Notification" toggle on individual monitors, and optionally displaying remaining days on public status pages.
Uptime Kuma provides built-in certificate expiry monitoring for any TLS-enabled monitor (HTTPS, TCP with STARTTLS, etc.). The feature operates at three configuration levels—global, per-monitor, and status-page—allowing granular control over when and how you receive alerts about impending certificate expirations.
Global Certificate Expiry Notification Settings
The global configuration defines how many days before expiration Uptime Kuma should trigger notifications. This applies across all monitors that have expiry notifications enabled.
Navigate to Settings → Certificate Expiry in the web interface. The UI component in src/components/settings/Notifications.vue (lines 58-87) renders an input list where you can add multiple threshold days:
<div class="mt-1 mb-3 ps-2 cert-exp-days col-12 col-xl-6">
<div v-for="day in settings.tlsExpiryNotifyDays" :key="day">
<span>{{ day }} days</span>
<button @click="removeTlsExpiryNotifDay(day)">Remove</button>
</div>
</div>
<ActionInput
v-model="tlsExpiryNotifInput"
type="number"
placeholder="Days (e.g., 30)"
:action="() => addTlsExpiryNotifDay(tlsExpiryNotifInput)"
/>
These values persist in the settings table under the key tlsExpiryNotifyDays. When the backend evaluates certificate status, it compares the certificate's daysRemaining against this array to determine if a notification should fire.
Per-Monitor Certificate Expiry Configuration
Even with global thresholds set, individual monitors must explicitly opt-in to certificate expiry monitoring. This prevents noise from monitors where TLS expiration is managed externally or irrelevant.
In the monitor edit page (src/pages/EditMonitor.vue, lines 1503-1514), locate the Certificate Expiry Notification checkbox:
<div class="my-3 form-check">
<input
id="expiry-notification"
v-model="monitor.expiryNotification"
type="checkbox"
:disabled="monitor.ignoreTls"
/>
<label for="expiry-notification">
Certificate Expiry Notification
</label>
<div class="form-text">
Receive notifications when the TLS certificate expires within the configured global threshold days.
</div>
</div>
When saved, this sets the expiry_notification column in the database (added via migration patch-add-certificate-expiry-status-page.sql). The backend logic in server/model/monitor.js uses this flag to determine whether to evaluate certificate expiry during the monitor check cycle.
Displaying Certificate Expiry on Status Pages
For public transparency, Uptime Kuma can display remaining certificate validity days on public status pages. This is controlled separately from notifications.
In the status page editor (src/pages/StatusPage.vue, lines 90-98), enable the toggle:
<div class="my-3 form-check form-switch">
<input
id="show-certificate-expiry"
v-model="config.showCertificateExpiry"
type="checkbox"
/>
<label for="show-certificate-expiry">
Show Certificate Expiry
</label>
</div>
This persists to the show_certificate_expiry column in the status page configuration. When rendered, src/components/PublicGroupList.vue (lines 258-261) displays the remaining days with color coding:
// Logic from PublicGroupList.vue
if (monitor.showCertificateExpiry && monitor.certExpiryDaysRemaining !== null) {
const days = monitor.certExpiryDaysRemaining;
const colorClass = days < 7 ? 'text-danger' : days < 30 ? 'text-warning' : 'text-success';
displayText = `Certificate expires in ${days} days`;
}
Backend Implementation: How Notifications Are Triggered
The certificate expiry monitoring logic resides primarily in server/util-server.js. When a monitor performs a TLS handshake, the system extracts certificate metadata and evaluates it against the configured thresholds.
Certificate Extraction and Storage
During the monitor check, the TLS certificate info is stored in the monitor object's tlsInfo field. The server/model/monitor.js method getCertExpiry() retrieves this data:
// server/model/monitor.js
getCertExpiry() {
if (this.tlsInfo && this.tlsInfo.certInfo) {
return {
certExpiryDaysRemaining: this.tlsInfo.certInfo.daysRemaining,
validCert: this.tlsInfo.certInfo.valid
};
}
return null;
}
Notification Evaluation Logic
The function checkCertExpiryNotifications in server/util-server.js (starting at line 916) determines whether to send alerts:
// server/util-server.js (simplified excerpt)
async function checkCertExpiryNotifications(monitor, tlsInfoObject) {
const daysRemaining = tlsInfoObject.certInfo.daysRemaining;
// Skip if monitor doesn't have expiry notifications enabled
if (!monitor.expiryNotification || daysRemaining == null) {
return;
}
// Load global settings
const settings = await Setting.getSettings();
const notifyDays = settings.tlsExpiryNotifyDays || [];
// Check if current days remaining matches any threshold
for (const targetDays of notifyDays) {
if (daysRemaining <= targetDays) {
await Notification.sendCertExpiry(monitor, targetDays, daysRemaining);
break; // Notify only once per check cycle
}
}
}
This function is invoked by monitor type implementations after successful TLS negotiation. For example, in server/monitor-types/globalping.js (line 500):
// After TLS check completes
if (tlsInfo) {
await checkCertExpiryNotifications(this, tlsInfo);
}
Summary
- Global thresholds are configured in Settings → Certificate Expiry, defining how many days before expiration notifications should trigger (
tlsExpiryNotifyDaysinsrc/components/settings/Notifications.vue). - Per-monitor enablement is controlled via the Certificate Expiry Notification checkbox on the monitor edit page, stored in the
expiry_notificationdatabase column (src/pages/EditMonitor.vue). - Public visibility is managed through the status page editor's Show Certificate Expiry toggle, which displays remaining days with color-coded urgency in
src/components/PublicGroupList.vue. - Backend logic in
server/util-server.js(checkCertExpiryNotifications) evaluates certificates against thresholds and queues notifications only for monitors with the expiry flag enabled.
Frequently Asked Questions
How do I add multiple notification thresholds for certificate expiry?
Navigate to Settings → Certificate Expiry in the Uptime Kuma dashboard. Use the input field to add multiple day values (e.g., 30, 14, 7). The system stores these in the tlsExpiryNotifyDays array and checks each certificate against every threshold, sending notifications when the remaining days are less than or equal to any configured value.
Why am I not receiving certificate expiry notifications?
First, verify that Certificate Expiry Notification is enabled on the specific monitor's edit page (the expiryNotification checkbox in src/pages/EditMonitor.vue). Second, ensure the monitor type supports TLS (HTTPS, TCP with STARTTLS). Third, check that global notification days are configured in Settings → Certificate Expiry. Finally, confirm the certificate is actually extractable—Uptime Kuma cannot monitor expiry for certificates on servers that reject TLS handshakes or use self-signed certs without proper chain validation.
Can I display certificate expiry information on public status pages?
Yes. Edit your status page and enable the Show Certificate Expiry toggle (found in src/pages/StatusPage.vue). When enabled, the public view (src/components/PublicGroupList.vue) displays the remaining days for each monitor's certificate, color-coded by urgency: red for less than 7 days, yellow for less than 30 days, and green for more than 30 days remaining.
Where is the certificate expiry notification logic implemented in the source code?
The core notification logic resides in server/util-server.js within the checkCertExpiryNotifications function (starting at line 916). This function compares the certificate's daysRemaining against the global tlsExpiryNotifyDays array and triggers notifications via Notification.sendCertExpiry(). The monitor model in server/model/monitor.js provides the getCertExpiry() method to extract certificate metadata, while individual monitor types (such as server/monitor-types/globalping.js) invoke the check after completing TLS handshakes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →