Invalid email `default.json` when retrieving cert from Let's Encrypt

1. Output of caddy version:

2.6.0

2. How I run Caddy:

I have a custom build with 2 private modules, 1 being a rest storage module that stores certificates in a Postgres DB. See Dockerfile below. Caddy uses the http loader to fetch its config from an API on startup.

a. System environment:

FROM caddy:2.6.0-builder AS builder

ARG ACCESS_TOKEN_USR="nothing"
ARG ACCESS_TOKEN_PWD="nothing"
ENV GOPRIVATE=github.com/appmasker/*

RUN printf "machine github.com\n\
    login ${ACCESS_TOKEN_USR}\n\
    password ${ACCESS_TOKEN_PWD}\n\
    \n\
    machine api.github.com\n\
    login ${ACCESS_TOKEN_USR}\n\
    password ${ACCESS_TOKEN_PWD}\n"\
    >> /root/.netrc
RUN chmod 600 /root/.netrc

RUN xcaddy build v2.6.0 \
  --with github.com/appmasker/caddy-admin-repeat \
  --with github.com/appmasker/caddy_rest_storage

FROM caddy:2.6.0

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

COPY managed-config.json /etc/caddy/

CMD ["caddy", "run", "--config", "/etc/caddy/managed-config.json"]  

b. Command:

See dockerfile above.

c. Service/unit/compose file:

Paste full file contents here.
Make sure backticks stay on their own lines,
and the post looks nice in the preview pane. -->

d. My complete Caddy config:

{
	"apps": {
		"http": {
			"servers": {
				"srv0": {
					"listen": [
						":443"
					],
					"routes": [
						{
							"match": [
								{
									"host": [
										"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"
									]
								}
							],
							"handle": [
								{
									"handler": "subroute",
									"routes": [
										{
											"handle": [
												{
													"body": "hello world again 2!",
													"handler": "static_response"
												}
											]
										}
									]
								}
							],
							"terminal": true
						}
					]
				}
			}
		},
		"tls": {
			"automation": {
				"policies": [
					{
						"subjects": [
							"localhost",
							"*.internal",
							"*.internal:10001"
						],
						"issuers": [
							{
								"module": "internal"
							}
						]
					}
				]
			}
		}
	},
	"storage": {
		"module": "rest",
		"endpoint": "https://api-dev.appmasker.com/tls/rest-storage",
		"api_key": "{env.X_API_KEY}"
	},
	"admin": {
		"enforce_origin": false,
		"listen": "707dd443.vm.0ab3f9d5-db25-448f-81d1-2126102d6009.internal:10001",
		"identity": {
			"identifiers": [
				"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"
			]
		},
		"remote": {
			"listen": ":10001",
			"access_control": [
				{
					"public_keys": [
						"<redacted>"
					]
				}
			]
		}
	}
}

3. The problem I’m having:

I’m have a host that needs a cert, but I’m being rejected by Let’s Encrypt and ZeroSSL for an invalid email address and contact URL (see logs below).

4. Error messages and/or full log output:

Certificates stored in postgres:

Logs

2022-10-15T06:01:45.195 app[707dd443] lax [info] {"level":"warn","ts":1665813705.1942053,"logger":"tls.issuance.zerossl","msg":"missing email address for ZeroSSL; it is strongly recommended to set one for next time"}

2022-10-15T06:01:45.290 app[707dd443] lax [info] {"level":"info","ts":1665813705.2905552,"logger":"tls","msg":"finished cleaning storage units"}

2022-10-15T06:01:45.293 app[707dd443] lax [info] {"level":"info","ts":1665813705.2937787,"logger":"tls.obtain","msg":"acquiring lock","identifier":"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"}

2022-10-15T06:01:45.313 app[707dd443] lax [info] {"level":"info","ts":1665813705.313234,"logger":"tls.obtain","msg":"lock acquired","identifier":"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"}

2022-10-15T06:01:45.346 app[707dd443] lax [info] {"level":"info","ts":1665813705.3465881,"logger":"tls.obtain","msg":"obtaining certificate","identifier":"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"}

2022-10-15T06:01:45.740 app[707dd443] lax [info] {"level":"error","ts":1665813705.7405906,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev","issuer":"acme-v02.api.letsencrypt.org-directory","error":"HTTP 400 urn:ietf:params:acme:error:invalidEmail - Error creating new account :: \"default.json\" is not a valid e-mail address"}

2022-10-15T06:01:45.774 app[707dd443] lax [info] {"level":"warn","ts":1665813705.774224,"logger":"http","msg":"missing email address for ZeroSSL; it is strongly recommended to set one for next time"}

2022-10-15T06:01:45.813 app[707dd443] lax [info] {"level":"info","ts":1665813705.8135107,"logger":"tls.issuance.zerossl","msg":"generated EAB credentials","key_id":"_WzrE9V2FVvjJcyu1mGR0A"}

2022-10-15T06:01:46.585 app[707dd443] lax [info] {"level":"info","ts":1665813706.5851433,"logger":"http","msg":"generated EAB credentials","key_id":"jHKLqzRiVc6MxPAAAPpz9Q"}

2022-10-15T06:01:48.540 app[707dd443] lax [info] {"level":"error","ts":1665813708.5404446,"logger":"tls.obtain","msg":"could not get certificate from issuer","identifier":"0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev","issuer":"acme.zerossl.com-v2-DV90","error":"HTTP 400 urn:ietf:params:acme:error:invalidContact - A contact URL for an account was invalid"}

2022-10-15T06:01:48.540 app[707dd443] lax [info] {"level":"error","ts":1665813708.5405643,"logger":"tls.obtain","msg":"will retry","error":"[0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev] Obtain: registering account [mailto:default.json] with server: attempt 1: https://acme.zerossl.com/v2/DV90/newAccount: HTTP 400 urn:ietf:params:acme:error:invalidContact - A contact URL for an account was invalid","attempt":1,"retrying_in":60,"elapsed":3.227213068,"max_duration":2592000}

2022-10-15T06:01:49.278 app[707dd443] lax [info] {"level":"info","ts":1665813709.2775877,"logger":"tls.issuance.zerossl","msg":"waiting on internal rate limiter","identifiers":["0ab3f9d5-db25-448f-81d1-2126102d6009.fly.dev"],"ca":"https://acme.zerossl.com/v2/DV90","account":""}

5. What I already tried:

The default.json invalid email that Let’s Encrypt complains about is likely coming from the cert key (id # 11 in the postgres screenshot). Based off of certmagic’s code, it seems like this is… correct? It seems like it is using the last part of the key as the email address, and for some reason mine is default.json. What am I missing?

6. Links to relevant resources:

Here is my rest storage module implementation.

This topic was automatically closed after 30 days. New replies are no longer allowed.