diff --git a/apps/console/src/pages/organizations/compliance-page/domain/_components/CompliancePageDomainCard.tsx b/apps/console/src/pages/organizations/compliance-page/domain/_components/CompliancePageDomainCard.tsx index c7f344555..e2c38623f 100644 --- a/apps/console/src/pages/organizations/compliance-page/domain/_components/CompliancePageDomainCard.tsx +++ b/apps/console/src/pages/organizations/compliance-page/domain/_components/CompliancePageDomainCard.tsx @@ -30,6 +30,7 @@ const fragment = graphql` fragment CompliancePageDomainCardFragment on CustomDomain { domain sslStatus + provisioningError canDelete: permission(action: "core:custom-domain:delete") ...CompliancePageDomainDialogFragment } @@ -52,7 +53,9 @@ export function CompliancePageDomainCard(props: { fKey: CompliancePageDomainCard
{__("Provisioning error")}
+{domain.provisioningError}
+
{__(
diff --git a/pkg/certmanager/provisioner.go b/pkg/certmanager/provisioner.go
index 60ba3df42..d287e6c76 100644
--- a/pkg/certmanager/provisioner.go
+++ b/pkg/certmanager/provisioner.go
@@ -298,6 +298,7 @@ func (p *Provisioner) resetStaleDomain(
fullDomain.HTTPChallengeKeyAuth = nil
fullDomain.HTTPChallengeURL = nil
fullDomain.HTTPOrderURL = nil
+ fullDomain.ProvisioningError = nil
fullDomain.SSLStatus = coredata.CustomDomainSSLStatusPending
if fullDomain.SSLLastAttemptAt != nil && time.Since(*fullDomain.SSLLastAttemptAt) > 24*time.Hour {
@@ -341,7 +342,13 @@ func (p *Provisioner) provisionDomainCertificate(
log.Error(err),
)
- return err
+ errMsg := err.Error()
+ domain.ProvisioningError = &errMsg
+ if err := domain.Update(ctx, tx, coredata.NewNoScope()); err != nil {
+ return fmt.Errorf("cannot update domain with provisioning error: %w", err)
+ }
+
+ return nil
}
if err := p.checkCAARecords(domain.Domain); err != nil {
@@ -352,9 +359,17 @@ func (p *Provisioner) provisionDomainCertificate(
log.Error(err),
)
- return err
+ errMsg := err.Error()
+ domain.ProvisioningError = &errMsg
+ if err := domain.Update(ctx, tx, coredata.NewNoScope()); err != nil {
+ return fmt.Errorf("cannot update domain with provisioning error: %w", err)
+ }
+
+ return nil
}
+ domain.ProvisioningError = nil
+
p.logger.InfoCtx(ctx, "DNS configuration verified, initiating HTTP challenge for domain", log.String("domain", domain.Domain))
challenge, err := p.acmeService.GetHTTPChallenge(ctx, domain.Domain)
@@ -406,6 +421,8 @@ func (p *Provisioner) provisionDomainCertificate(
log.Error(err),
)
+ errMsg := err.Error()
+ domain.ProvisioningError = &errMsg
domain.SSLRetryCount = domain.SSLRetryCount + 1
domain.SSLLastAttemptAt = new(time.Now())
@@ -445,6 +462,7 @@ func (p *Provisioner) provisionDomainCertificate(
log.Time("expires_at", cert.ExpiresAt),
)
+ domain.ProvisioningError = nil
domain.SSLCertificatePEM = cert.CertPEM
if err := domain.EncryptPrivateKey(cert.KeyPEM, p.encryptionKey); err != nil {
return fmt.Errorf("cannot encrypt private key: %w", err)
diff --git a/pkg/coredata/custom_domain.go b/pkg/coredata/custom_domain.go
index c8b20c9ac..12b63ca61 100644
--- a/pkg/coredata/custom_domain.go
+++ b/pkg/coredata/custom_domain.go
@@ -47,6 +47,7 @@ type (
SSLExpiresAt *time.Time `db:"ssl_expires_at"`
SSLRetryCount int `db:"ssl_retry_count"`
SSLLastAttemptAt *time.Time `db:"ssl_last_attempt_at"`
+ ProvisioningError *string `db:"provisioning_error"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
@@ -171,6 +172,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -227,6 +229,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -283,6 +286,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -339,6 +343,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -401,6 +406,7 @@ INSERT INTO custom_domains (
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
) VALUES (
@@ -419,6 +425,7 @@ INSERT INTO custom_domains (
@ssl_expires_at,
@ssl_retry_count,
@ssl_last_attempt_at,
+ @provisioning_error,
@created_at,
@updated_at
)
@@ -440,6 +447,7 @@ INSERT INTO custom_domains (
"ssl_expires_at": cd.SSLExpiresAt,
"ssl_retry_count": cd.SSLRetryCount,
"ssl_last_attempt_at": cd.SSLLastAttemptAt,
+ "provisioning_error": cd.ProvisioningError,
"created_at": cd.CreatedAt,
"updated_at": cd.UpdatedAt,
}
@@ -485,6 +493,7 @@ SET
ssl_expires_at = @ssl_expires_at,
ssl_retry_count = @ssl_retry_count,
ssl_last_attempt_at = @ssl_last_attempt_at,
+ provisioning_error = @provisioning_error,
updated_at = @updated_at
WHERE
%s
@@ -506,6 +515,7 @@ WHERE
"ssl_expires_at": cd.SSLExpiresAt,
"ssl_retry_count": cd.SSLRetryCount,
"ssl_last_attempt_at": cd.SSLLastAttemptAt,
+ "provisioning_error": cd.ProvisioningError,
"updated_at": time.Now(),
}
maps.Copy(args, scope.SQLArguments())
@@ -567,6 +577,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -618,6 +629,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -670,6 +682,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -725,6 +738,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
@@ -775,6 +789,7 @@ SELECT
ssl_expires_at,
ssl_retry_count,
ssl_last_attempt_at,
+ provisioning_error,
created_at,
updated_at
FROM
diff --git a/pkg/coredata/migrations/20260423T074540Z.sql b/pkg/coredata/migrations/20260423T074540Z.sql
new file mode 100644
index 000000000..0c90b539a
--- /dev/null
+++ b/pkg/coredata/migrations/20260423T074540Z.sql
@@ -0,0 +1,15 @@
+-- Copyright (c) 2026 Probo Inc