Bulk renew
Select many certificates at once and submit a single action. The
backend fans out individual renewal jobs, tracks per-cert
progress, and aggregates the outcome. Idempotency keys prevent
double-submission of the same batch; partial failures surface
as partial_failure with the failed certs callable
out for human attention.
01Why bulk vs individual
- CA/B Forum shortening. SC-081 (47-day certs) means your renewal cadence goes from every 60–90 days to every 20–30. Bulk actions are how you absorb that volume without clicking a thousand buttons a week.
- Quarterly audits. "Renew every cert issued before date X" is a common ask — bulk action + filter.
- Rate-limit planning. A bulk action surfaces the combined zone rate-limit picture before you submit, so you don't blow through a weekly quota halfway through.
02Prerequisites
- Operator role on the project.
- Each selected cert has a healthy issuer + auto-renew config (or you're explicitly using bulk-renew to restart a stuck cert).
03Submit a bulk action
- Certificates → filter / search to your working set.
- Tick the row checkboxes (header checkbox = select all on current page; Select all matching filter for the full set).
- Click Bulk renew. A confirmation dialog shows:
- Selected count.
- Per-zone rate-limit projection (green / amber / red).
- Preflight warnings per cert (renewal would break pinned client, policy conflict, etc.).
- Confirm. The backend creates a
bulk_actionrecord with a SHA-256 idempotency key over the sorted cert-id list. - Track progress under Jobs → Bulk actions.
04Bulk action states
| State | Meaning |
|---|---|
pending | Record created, individual jobs being enqueued. |
in_progress | At least one job running, at least one still pending. |
completed | Every cert renewed successfully. |
partial_failure | Some succeeded, some failed. See the per-cert breakdown. |
failed | All jobs failed (rare; usually a config issue upstream). |
cancelled | Operator cancelled — in-flight jobs finish but pending jobs are dropped. |
05Idempotency
The idempotency key is a SHA-256 of the sorted cert-id list + the action type. Submitting the same set twice within the TTL (24 h by default) returns the original action, not a new one. This protects against accidental double-clicks and race conditions between API callers.
# Same set, submitted twice → second returns the original action ID
curl -X POST $API/bulk-actions \
-H "Authorization: Bearer $KEY" \
-d '{"type":"renew","certificate_ids":["a","b","c"]}'
# → {"id":"act_abc","status":"pending"}
curl -X POST $API/bulk-actions -d '…same body…'
# → {"id":"act_abc","status":"in_progress"} ← same record, updated status
06Per-cert tracking
The bulk-action detail page shows a progress panel with every
cert's state. States: pending, succeeded,
failed (with error), skipped (e.g. cert
already within its renewal window or in a non-renewable state).
Atomic MongoDB $inc/$push with
$slice keeps the UI counters correct under
concurrent worker updates.
07Partial failure handling
When the bulk action finishes in partial_failure:
- The detail page shows the failed set first, sorted by error class.
- Each failed cert carries the same error surface as an individual renewal — you can click through to the cert's job detail for logs.
- Retry the failed set with a single click: the Retry failed button creates a new bulk action scoped to just the failures. This is a new record with a new idempotency key — not a merge into the original.
08Cancel
Click Cancel on an in-progress bulk action. Pending
per-cert jobs are dropped; in-flight jobs (already polled by a
worker) finish their current attempt and then stop. The action
transitions to cancelled once every pending/in-flight
job settles.
09Rate-limit pre-check
Before you confirm, the dialog shows a per-zone projection based on the current 7-day rolling issuance count vs. the CA's declared weekly limits (currently 50/week for Let's Encrypt registered-domain bucket). Zones projected to exceed limits are highlighted red with a warning that those certs will be deferred or fail. Consider staggering the batch.
10API
POST /api/v1/projects/{projectId}/bulk-actions
{
"type": "renew",
"certificate_ids": ["cert_a", "cert_b", ...]
}
GET /api/v1/projects/{projectId}/bulk-actions/{actionId}
# → {
# "id":"act_abc",
# "status":"in_progress",
# "counts":{"total":12,"succeeded":5,"failed":1,"pending":6},
# "failures":[ {"certificate_id":"...", "error_class":"network", ...} ]
# }
11Troubleshooting
Bulk action deferred for rate-limit
CA's weekly quota saturated. Wait for the counter to roll off (shown on the zone page) or split the batch over multiple weeks.
"Duplicate bulk action"
Same cert-id set submitted within 24 h. If you genuinely want a second execution, add or remove one cert from the selection — that changes the idempotency key.
Many certs marked skipped
They were outside their renewal window or in a terminal state. The skip is safe — no work was wasted. Re-run the bulk action with a filter that excludes those certs to keep the counts clean.