Skip to content

Certbot has a ReadTimeout error if finalization takes >45 seconds with Sectigo's ACME #22

Description

@markjonestx

Hello! I deployed your acme-proxy in our DC to experiment and see if it would allow me to issue trusted certs to our semi-air-gapped network, but our Certbot-based clients are unfortunately timing out waiting for a response. Our acme.sh clients do not have the issue.

The Testing Environment:

  • acme-proxy directly from the main branch, commit 7f7f416
  • certbot 3.1.0 on an EL9.7 box
  • ACME Proxy running on a EL10.1 box
  • InCommon's "Universal ACME" provider

The command I used was on the EL9.7 box is:

certbot certonly -d <domain_scrubbed> --webroot -w /var/lib/acme-challenge/ --cert-name incommon --server https://<acme_proxy>/acme/acme/directory --agree-tos --email <email_scrubbed> --non-interactive

When the error first occurred, I tried to add --issuance-timeout 10000 to Certbot, but it doesn't seem to affect the socket timeout.

Here's the logs on the ACME Proxy

2026/04/03 00:45:03 [INFO] acme: Registering account for <email_scrubbed>
2026/04/03 00:45:03 INFO processing certificate request domains=[<domain_scrubbed>]
2026/04/03 00:45:03 [INFO] [<domain_scrubbed>] acme: Obtaining bundled SAN certificate given a CSR
2026/04/03 00:45:18 [INFO] [<domain_scrubbed>] AuthURL: https://acme.enterprise.sectigo.com/authorization/<scrubbed>/0/always-valid
2026/04/03 00:45:18 [INFO] [<domain_scrubbed>] acme: authorization already valid; skipping challenge
2026/04/03 00:45:18 [INFO] [<domain_scrubbed>] acme: Validations succeeded; requesting certificates
2026/04/03 00:45:30 [INFO] Wait for certificate [timeout: 30s, interval: 500ms]

# <- Here is where Certbot times out

2026/04/03 00:46:07 [INFO] [<domain_scrubbed>] Server responded with a certificate.
2026/04/03 00:46:07 INFO obtained certificate from external CA domains=[<domain_scrubbed>]

The error from Certbot's log:

Traceback (most recent call last):
  File "/bin/certbot", line 8, in <module>
    sys.exit(main())
  File "/usr/lib/python3.9/site-packages/certbot/main.py", line 19, in main
    return internal_main.main(cli_args)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 1873, in main
    return config.func(config, plugins)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 1579, in certonly
    lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/main.py", line 142, in _get_and_save_cert
    lineage = le_client.obtain_and_enroll_certificate(domains, certname)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 518, in obtain_and_enroll_certificate
    cert, chain, key, _ = self.obtain_certificate(domains)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 452, in obtain_certificate
    cert, chain = self.obtain_certificate_from_csr(csr, orderr)
  File "/usr/lib/python3.9/site-packages/certbot/_internal/client.py", line 342, in obtain_certificate_from_csr
    orderr = self.acme.finalize_order(
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 279, in finalize_order
    self.begin_finalization(orderr)
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 230, in begin_finalization
    res = self._post(orderr.body.finalize, wrapped_csr)
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 370, in _post
    return self.net.post(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 743, in post
    return self._post_once(*args, **kwargs)
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 755, in _post_once
    response = self._send_request('POST', url, data=data, **kwargs)
  File "/usr/lib/python3.9/site-packages/acme/client.py", line 652, in _send_request
    response = self.session.request(method, url, *args, **kwargs)
  File "/usr/lib/python3.9/site-packages/requests/sessions.py", line 544, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3.9/site-packages/requests/sessions.py", line 657, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3.9/site-packages/requests/adapters.py", line 702, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='<acme_proxy>', port=443): Read timed out. (read timeout=45)
2026-04-03 00:45:33,204:ERROR:certbot._internal.log:An unexpected error occurred:
2026-04-03 00:45:33,204:ERROR:certbot._internal.log:requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='<acme_proxy>', port=443): Read timed out. (read timeout=45)

After rg-ing my way through Certbot's code and skimming the RFC, I think what is happening is that Certbot expects a { "status": "processing" } response with an optional Retry-After header set to some amount of time while the server waits for a certificate to generate.

I think the specific function is poll_finalization in Certbot's acme/src/acme/client.py:

277             elif body.status == messages.STATUS_PROCESSING:
278                 # "processing": The certificate is being issued.  Send a POST-as-GET request after
279                 # the time given in the Retry-After header field of the response, if any.
280                 retry_after = self.retry_after(response, 1)
281                 # Whatever Retry-After the ACME server requests, the polling must not take
282                 # longer than the overall deadline
283                 retry_after = min(retry_after, deadline)
284                 sleep_seconds = (retry_after - datetime.datetime.now()).total_seconds()

If you need any additional information, just let know! Thank you for putting this project together!

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingupstream issueissue related to upstream `step-ca` or some upstream dependency. Fix may take longer than expected.

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions