Skip to content

EuroDNS DNS-01 challenge fails — bundled certbot-dns-eurodns 0.0.4 plugin uses wrong default endpoint and incompatible record-field name with EuroDNS v2 API #5516

@alexisskeates

Description

@alexisskeates

Checklist

  • Have you pulled and found the error with jc21/nginx-proxy-manager:latest
    docker image?
    • Yes
  • Are you sure you're not using someone else's docker image?
    • Yes
  • Have you searched for similar issues (both open and closed)?
    • Yes

Describe the bug

Note: This bug was diagnosed with the help of Claude AI (Anthropic)
— pairing the operator on log inspection, plugin source review, and
minimal-reproduction patching against the EuroDNS v2 API spec.

Requesting a Let's Encrypt certificate via the EuroDNS DNS-01 challenge
always fails. The bundled certbot-dns-eurodns 0.0.4 plugin (from the
abandoned [mgarriga73/certbot-dns-eurodns](https://github.com/mgarriga73/certb
ot-dns-eurodns) repo) has two bugs against the current EuroDNS v2 REST API:

Bug 1 — wrong default endpoint URL. The plugin builds API URLs as
endpoint + zone_name. The legacy v1 path
https://rest-api.eurodns.com/user-api-gateway/proxy (which most online
docs/snippets show, and which appears to be NPM's effective default) returns
404 for every zone lookup, so _getRealDomain exhausts all guesses and
surfaces:

EuroDNS API Failed to find domain <domain> (Does your account have access to
this domain?)                                                                 

The correct v2 endpoint is https://rest-api.eurodns.com/dns-zones/
(trailing slash matters — the plugin concatenates endpoint + zone). Verified
against the v2 OpenAPI spec at https://docapi.eurodns.com/openapi.json.

Bug 2 — plugin sends 'data' field, v2 API requires 'rdata'. Once the
endpoint is corrected, the validation step fails with:

EuroDNS API Error during _prepZone: Unexpected technical error, please try
again or contact support

dns_eurodns.py (line ~121, in addRecord) appends a TXT record with field
'data':

zoneJSON['records'].append({
    'type': self.type,
    'host': host,
    'ttl': self.ttl,
    'data': validation       # v2 API rejects — field is 'rdata'
})                                                                            

…and references the same field on cleanup (line ~149, in delRecord's filter
lambda):

record['data'] != validation

The v2 OpenAPI schema defines the field as rdata. Sending data causes
_prepZone (which POSTs the modified zone to /dns-zones/{zone}/check) to
return the generic "Unexpected technical error".

Two-line patch that fixes both write and cleanup paths:

-    'data': validation
+    'rdata': validation                                                      
-    record['data']                                          
+    record['rdata']

After patching, certbot --dry-run -d '*.example.com' against LE staging
completes the full cycle — TXT record added, validated, removed — zone
unchanged afterwards. Confirmed working end-to-end with a real wildcard
certificate.

Suggested fixes for NPM:

  1. Patch the bundled plugin in NPM's Dockerfile with the two-line sed (the
    upstream plugin repo appears abandoned at 0.0.4 — last commit years old).
  2. Update the default dns_eurodns_endpoint shown in the credentials block to
    https://rest-api.eurodns.com/dns-zones/. This alone fixes Bug 1 but leaves
    Bug 2.
  3. Replace the plugin with a maintained alternative if one exists.

User-side workaround until a fix lands — mount a patched dns_eurodns.py
over the original:

volumes:
  - ./patches/dns_eurodns.py:/opt/certbot/lib/python3.11/site-packages/certbot
_dns_eurodns/dns_eurodns.py:ro                                                

Nginx Proxy Manager Version

2.14.0 (jc21/nginx-proxy-manager:latest, image pulled 2026-05).

To Reproduce

Steps to reproduce the behavior:

  1. Generate API Access credentials in the EuroDNS dashboard (Application ID +
    API Key — distinct from per-record Dynamic DNS credentials).
  2. In NPM go to SSL CertificatesAdd SSL CertificateLet's Encrypt.
  3. Enter a domain (e.g. *.example.com), tick Use a DNS Challenge, choose
    EuroDNS as the provider.
  4. In the Credentials File Content box, paste:
    dns_eurodns_applicationId = <your app id>                 
    dns_eurodns_apiKey         = <your api key>
    dns_eurodns_endpoint       =                                               

https://rest-api.eurodns.com/user-api-gateway/proxy
(the endpoint value commonly shown in NPM tutorials and EuroDNS plugin examples online) 5. Tick *I Agree to the Let's Encrypt Terms of Service*, then *Save*. 6. See error in `data/logs/letsencrypt.log`:
EuroDNS API Failed to find domain (Does your account have access
to this domain?)
7. Edit credentials, change endpoint to `https://rest-api.eurodns.com/dns-zones/`, save again. 8. See the next error:
EuroDNS API Error during _prepZone: Unexpected technical error, please try
again or contact support

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions