Error when activating dns challenge

1. The problem I’m having:

Hi folks!
Im having trouble activating and verifying configuration for dns-challenge instead of http-challenge for certificate renewal/create.
Inbound port 80 is closed, it was open earlier and it then got a valid certificate
The only place im seeing an error is when I run “caddy validate”
When restarting service after deleting certificate manually it reapears, I suspect is pulls the same cert(which still is valid)
No TXT record is being created.
The api key and secret are provided and looks like are seen by the serivce/caddy
What helps to get rid of the error is to direclty specify keys(correct or wrong does not matter) inside the Caddyfile but when deleting certificate and restarting the service the same behaviour is observed.(no logs are reporting any errors nor can I see any attempt to use the dns challenge)

2. Error messages and/or full log output:

#caddy validate --config /etc/caddy/Caddyfile
Error: loading http app module: provision http: getting tls app: loading tls app module: provision tls: provisioning automation policy 0: loading TLS automation management module: position 0: loading module ‘acme’: provision tls.issuance.acme: loading DNS provider module: loading module ‘spaceship’: provision dns.providers.spaceship: spaceship: api_key and api_secret are required

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

3. Caddy version:

v2.11.2 h1:iOlpsSiSKqEW+SIXrcZsZ/NO74SzB/ycqqvAIEfIm64=

4. How I installed and ran Caddy:

used xcaddy to build caddy binary with dns provider support

caddy list-modules | grep dns

tls.ech.publishers.dns
dns.providers.spaceship

a. System environment:

6.12.85+deb13-amd64

b. Command:

runs as a system service


c. Service/unit/compose file:


d. My complete Caddy config:

global config:
tls {
dns spaceship {
api_key {env.LIBDNS_SPACESHIP_APIKEY}
api_secret {env.LIBDNS_SPACESHIP_APISECRET}
}
}
#Alo tried to use:
acme_dns spaceship {
api_key {env.LIBDNS_SPACESHIP_APIKEY}
api_secret {env.LIBDNS_SPACESHIP_APISECRET}
}
#tried both with .env file and directly inside system-service
#works to get rid of the validation error(does not matter correct or wrong credentials):
tls {
dns spaceship YOUR_API_KEY YOUR_API_SECRET
}

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

5. Links to relevant resources:

The key issue is probably that the DNS provider credentials are empty when Caddy provisions the config.

For provider config, I would use Caddyfile env substitution, not runtime placeholder syntax:

{
    acme_dns spaceship {
        api_key {$LIBDNS_SPACESHIP_APIKEY}
        api_secret {$LIBDNS_SPACESHIP_APISECRET}
    }
}

Then make sure those variables are actually visible to the Caddy service. A .env file is not loaded automatically by systemd; you need something like:

EnvironmentFile=/etc/caddy/spaceship.env

Also, caddy validate only sees the environment of the shell running that command, not necessarily the systemd service environment.

Once the config validates, Caddy may still not create a TXT record immediately if it already has a valid certificate. The TXT record is only created during an actual DNS-01 issuance/renewal attempt.

Hi and thanks for taking the time!
I’ve tried to change to env substitution(copy/paste your code) and now get another error about missing key/secret when validating the config:

Error: adapting config using caddyfile: parsing caddyfile tokens for ‘acme_dns’: api_key requires value, at /etc/caddy/Caddyfile:4

EnvironmentFile= directive is present in the service-file:

[Unit]
Description=Caddy
Documentation=Welcome — Caddy Documentation
After=network.target network-online.target
Requires=network-online.target

[Service]
User=caddy
Group=caddy
ExecStart=
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
EnvironmentFile=/etc/caddy/caddy.env

[Install]
WantedBy=multi-user.target

# cat /etc/caddy/caddy.env
LIBDNS_SPACESHIP_APIKEY=API_KEY
LIBDNS_SPACESHIP_APISECRET=API_SECRET

when starting the service, it clearly sees the variables which are listed in the service-startup.

That error is from the environment of the caddy validate command, not necessarily from the systemd service.

{$LIBDNS_SPACESHIP_APIKEY} is substituted while the Caddyfile is adapted. If you run caddy validate manually and that shell does not have the variables set, Caddy sees an empty value and the parser reports:

api_key requires value

Since caddy run --environ shows the variables when started through systemd, the service environment is probably fine.

To validate manually, source the env file first:

set -a

. /etc/caddy/caddy.env

set +a

caddy validate --config /etc/caddy/Caddyfile

Or validate as the same user if needed:

sudo -u caddy sh -c ‘set -a; . /etc/caddy/caddy.env; set +a; caddy validate --config /etc/caddy/Caddyfile’

After that, restart through systemd and check the journal. The TXT record still will not appear unless Caddy is actually attempting issuance/renewal.

Thanks!

Both methods of checking the configuration resultet in “Valid configuration”

That only means that validation is not the whole answer or is an answer when executed in right environment, as you’ve explained in your answers.

for the cert-status I guess it’ll have to wait until actual renewal interval comes to see if the api works as it should.

Again, thanks for the time and the explanation!

No worries. Enjoy!