Skip to content

Commit e27c219

Browse files
estenryeclaude
andcommitted
fix: revert StatusProcessing to polling (revert pf9.5 re-finalization)
ZeroSSL ACME API investigation confirmed that the 403 orderNotReady on the first finalize call is a false rejection — ZeroSSL internally accepts the finalization and transitions the order to 'processing'. POSTing to the finalize URL again while the order is in 'processing' is rejected with 403 (correct per RFC: you don't re-finalize a processing order). The correct behavior is to poll the order URL until ZeroSSL transitions to 'valid'. pf9.4's finalizeOrder 403 handler correctly detects the processing state and re-queues for polling. The long processing time (25-30 min observed on 2026-06-17) is a ZeroSSL service quality issue, not a cert-manager issue — likely due to account-level rate limiting from many test runs in a single day. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f56e1cd commit e27c219

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

pkg/controller/acmeorders/sync.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,22 @@ func (c *controller) Sync(ctx context.Context, o *cmacme.Order) (err error) {
246246
// valid or invalid.
247247
//
248248
// ZeroSSL exhibits non-standard ACME behavior: it returns 403 orderNotReady on the first finalize
249-
// call and transitions the order to 'processing', but the order never self-transitions to 'valid'.
250-
// A second finalize POST is required to trigger actual certificate issuance. We attempt re-finalization
251-
// here; if ZeroSSL is not ready, it will return 403 again and the order cycles back to this case.
249+
// call (even when the order is in 'ready' state), but internally accepts the finalization and
250+
// transitions the order to 'processing'. The finalizeOrder 403 handler (below) detects this and
251+
// sets the local order state to Processing. Subsequent attempts to re-POST to the finalize URL are
252+
// rejected with 403 since the order is already being processed. The correct behavior is to poll
253+
// until ZeroSSL transitions the order to 'valid' and a certificate URL is available.
252254
case acmeOrder.Status == acmeapi.StatusProcessing:
253-
log.V(logf.InfoLevel).Info("Order is in processing state, re-attempting finalization to handle servers that require a second finalize call")
255+
log.V(logf.InfoLevel).Info("Order is in processing state, waiting for ACME server to update the status of the order...")
254256
c.setOrderState(&o.Status, string(cmacme.Processing))
255-
return c.finalizeOrder(ctx, cl, o, genericIssuer)
257+
258+
// Re-queue the Order to be processed again after RequeuePeriod has passed.
259+
c.scheduledWorkQueue.Add(types.NamespacedName{
260+
Name: o.Name,
261+
Namespace: o.Namespace,
262+
}, RequeuePeriod)
263+
264+
return nil
256265

257266
case !anyChallengesFailed(challenges) && allChallengesFinal(challenges):
258267
log.V(logf.DebugLevel).Info("All challenges are in a final state, updating order state")

0 commit comments

Comments
 (0)