From 2efdd2f16b716bc82b65000a4573b8a11c546386 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Fri, 27 Mar 2026 19:26:39 +0000 Subject: [PATCH] fix(dcrouter): retry auto certificate provisioning after SmartAcme becomes ready --- changelog.md | 7 +++++++ ts/00_commitinfo_data.ts | 2 +- ts/classes.dcrouter.ts | 30 ++++++++++++++++++++++++++++++ ts_web/00_commitinfo_data.ts | 2 +- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 8968a87..5ddfb4b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-03-27 - 11.12.1 - fix(dcrouter) +retry auto certificate provisioning after SmartAcme becomes ready + +- detects certificates that failed during startup before the DNS-01 provider was available +- clears provisioning backoff and failed status for affected domains before retrying +- re-triggers auto certificate provisioning for SmartProxy routes once SmartAcme is ready + ## 2026-03-27 - 11.12.0 - feat(web-ui) pause dashboard polling, sockets, and chart updates when the tab is hidden diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 0031fab..1c343b5 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '11.12.0', + version: '11.12.1', description: 'A multifaceted routing service handling mail and SMS delivery functions.' } diff --git a/ts/classes.dcrouter.ts b/ts/classes.dcrouter.ts index 01e9cbc..1e8c755 100644 --- a/ts/classes.dcrouter.ts +++ b/ts/classes.dcrouter.ts @@ -388,6 +388,36 @@ export class DcRouter { await this.smartAcme.start(); this.smartAcmeReady = true; logger.log('info', 'SmartAcme DNS-01 provider is now ready'); + + // Re-provision any certificates that failed during the startup window + // (before SmartAcme was ready — the certProvisionFunction returned 'http01' + // which fails because Rust ACME is disabled when certProvisionFunction is set) + if (this.smartProxy) { + const failedDomains = [...this.certificateStatusMap.entries()] + .filter(([_, status]) => status.status === 'failed') + .map(([domain]) => domain); + + if (failedDomains.length > 0) { + logger.log('info', `Re-provisioning ${failedDomains.length} certificates that failed before SmartAcme was ready`); + // Clear backoff and status for failed domains — these failures were from the startup race + for (const domain of failedDomains) { + if (this.certProvisionScheduler) { + await this.certProvisionScheduler.clearBackoff(domain); + } + this.certificateStatusMap.delete(domain); + } + // Re-trigger provisioning for all auto-cert routes + const routes = this.smartProxy.routeManager.getRoutes(); + for (const route of routes) { + const tls = (route as any).action?.tls; + if (tls && tls.certificate === 'auto') { + this.smartProxy.provisionCertificate(route.name).catch((err: any) => { + logger.log('warn', `Re-provision for route '${route.name}' failed: ${err?.message || err}`); + }); + } + } + } + } } }) .withStop(async () => { diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 0031fab..1c343b5 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@serve.zone/dcrouter', - version: '11.12.0', + version: '11.12.1', description: 'A multifaceted routing service handling mail and SMS delivery functions.' }