Hello,
I’m experiencing an issue with domain verification while using a custom ACME client based on the acme-tiny
library. The client has been functioning correctly, but it suddenly started failing during the verification process. Below are the details of the error and the relevant code snippets.
Error Details
Order created! {'status': 'pending', 'expires': '2024-12-02T05:59:03Z', 'identifiers': [{'type': 'dns', 'value': ab.com'}], 'authorizations': ['https://acme-staging-v02.api.letsencrypt.org/acme/authz/XXX/xxx'], 'finalize': 'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/XXX/XXX'}
When attempting to verify the domain, I receive the following error:
Response Code: 404
Response: {'type': 'urn:ietf:params:acme:error:malformed', 'detail': 'No such challenge', 'status': 404}
Code Snippet
Here is the relevant part of the code where the domain verification occurs:
def post_verify_domain(self, domain, path, keyauthorization, challenge, is_apex=False, is_cdn=False):
authoritative_ip, auth_cname = get_domain_ip_authoritative_nameserver(domain, allow_multiple_ips=is_cdn)
host = authoritative_ip
wellknown_url = "http://{}{}".format(host, path)
resp_data = None
try:
session = requests.Session()
session.mount('http://', HostHeaderSSLAdapter(custom_domain=domain, domain_to_replace=authoritative_ip))
session.mount('https://', HostHeaderSSLAdapter(custom_domain=domain, domain_to_replace=authoritative_ip))
resp_data = session.get(wellknown_url, headers={"User-Agent": "Custom Client"}, verify=False, timeout=5).text.strip()
if resp_data != keyauthorization:
raise AssertionError()
except (IOError, AssertionError):
raise TokenComparisonFailedException(
"Failed token comparison; Expected token: {} - Received token: {}".format(keyauthorization, resp_data or "No token due to Request Exception")
)
# Submit the challenge
try:
self._send_signed_request(challenge['url'], {}, "Error submitting challenges: {0}".format(domain))
except Exception as e:
raise LetsEncryptVerificationFailedException("{}".format(e))
# Check authorization status
auth_url = challenge['url'].split('/')[:-1]
auth_url[-2] = 'authz-v3'
auth_url = '/'.join(auth_url)
try:
authorization = self._poll_until_not(auth_url, ["pending"], "Error checking challenge status for {0}".format(domain))
if authorization['status'] != 'valid':
raise LetsEncryptVerificationFailedException("Challenge did not pass for {0}: {1}".format(domain, authorization))
except TimeoutError:
raise LetsEncryptVerificationFailedException("Timeout for challenge of domain {0}: pending too long".format(domain))
Additional Information
- The client is using ACME v02, and I have verified that the DNS records are correctly set up.
- The challenge URL is being constructed from the authorization response, but it seems to be returning a 404 error.
Request for Help
I would appreciate any insights or suggestions on how to troubleshoot this issue further. Are there any common pitfalls with domain verification in ACME that I should be aware of?
Thank you for your assistance!