No Subject for internal certificates

1. The problem I’m having:

I’m trying to use the internal caddy tls features for local testing and development. However, the certificates issued by the internal PKI don’t have any subject set. I can’t find how to configure this subject (or I didn’t understand the docs):

2. Error messages and/or full log output:

2026/01/06 09:02:53.426 INFO    maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined
2026/01/06 09:02:53.427 INFO    GOMEMLIMIT is updated   {"package": "github.com/KimMachineGun/automemlimit/memlimit", "GOMEMLIMIT": 13980837888, "previous": 9223372036854775807}
2026/01/06 09:02:53.427 INFO    using config from file  {"file": "conf/Caddyfile"}
2026/01/06 09:02:53.429 INFO    adapted config to JSON  {"adapter": "caddyfile"}
2026/01/06 09:02:53.429 WARN    Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies    {"adapter": "caddyfile", "file": "conf/Caddyfile", "line": 2}
2026/01/06 09:02:53.431 INFO    admin   admin endpoint started  {"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]}
2026/01/06 09:02:53.432 INFO    tls.cache.maintenance   started background certificate maintenance      {"cache": "0xc0009ca300"}
2026/01/06 09:02:53.432 INFO    http.auto_https enabling automatic HTTP->HTTPS redirects        {"server_name": "srv0"}
2026/01/06 09:02:53.433 INFO    http    enabling HTTP/3 listener        {"addr": ":10443"}
2026/01/06 09:02:53.433 INFO    failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 7168 kiB, got: 416 kiB). See https://github.com/quic-go/quic-go/wiki/UDP-Buffer-Sizes for details.
2026/01/06 09:02:53.433 INFO    http.log        server running  {"name": "srv0", "protocols": ["h1", "h2", "h3"]}
2026/01/06 09:02:53.434 WARN    http    HTTP/2 skipped because it requires TLS  {"network": "tcp", "addr": ":8099"}
2026/01/06 09:02:53.434 WARN    http    HTTP/3 skipped because it requires TLS  {"network": "tcp", "addr": ":8099"}
2026/01/06 09:02:53.434 INFO    http.log        server running  {"name": "remaining_auto_https_redirects", "protocols": ["h1", "h2", "h3"]}
2026/01/06 09:02:53.434 INFO    http    enabling automatic TLS certificate management   {"domains": ["mastodon.local"]}
2026/01/06 09:02:53.434 INFO    pki.ca.local    root certificate is already trusted by system   {"path": "storage:pki/authorities/local/root.crt"}
2026/01/06 09:02:53.435 INFO    autosaved config (load with --resume flag)      {"file": "/home/ploeger/.config/caddy/autosave.json"}
2026/01/06 09:02:53.435 INFO    serving initial configuration
2026/01/06 09:02:53.438 INFO    tls     cleaning storage unit   {"storage": "FileStorage:/home/ploeger/.local/share/caddy"}
2026/01/06 09:02:53.440 INFO    tls.obtain      acquiring lock  {"identifier": "mastodon.local"}
2026/01/06 09:02:53.442 INFO    tls     finished cleaning storage units
2026/01/06 09:02:53.443 INFO    tls.obtain      lock acquired   {"identifier": "mastodon.local"}
2026/01/06 09:02:53.444 INFO    tls.obtain      obtaining certificate   {"identifier": "mastodon.local"}
2026/01/06 09:02:53.452 INFO    tls.obtain      certificate obtained successfully       {"identifier": "mastodon.local", "issuer": "local"}
2026/01/06 09:02:53.452 INFO    tls.obtain      releasing lock  {"identifier": "mastodon.local"}
2026/01/06 09:02:53.453 WARN    tls     stapling OCSP   {"identifiers": ["mastodon.local"]}
^C2026/01/06 09:03:45.561       INFO    shutting down   {"signal": "SIGINT"}
2026/01/06 09:03:45.561 WARN    exiting; byeee!! 👋     {"signal": "SIGINT"}
2026/01/06 09:03:45.561 INFO    http    servers shutting down with eternal grace period
2026/01/06 09:03:45.562 INFO    admin   stopped previous server {"address": "localhost:2019"}
2026/01/06 09:03:45.562 INFO    shutdown complete       {"signal": "SIGINT", "exit_code": 0}

3. Caddy version:

v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=

4. How I installed and ran Caddy:

Downloaded Caddy from the website and ran:

caddy run --config conf/Caddyfile

a. System environment:

Linux AMD64, Bazzite OS

b. Command:

$ caddy run --config conf/Caddyfile
# mastodon.local is mapped to 127.0.0.1 in my hosts
$ openssl s_client -connect mastodon.local:10443 < /dev/null 2>&1 | grep subject
subject=

c. Service/unit/compose file:

None

d. My complete Caddy config:

{
    http_port 8099
}
https://mastodon.local:10443
{
    tls internal 
    reverse_proxy * {
        to web:3000
    }
}

5. Links to relevant resources:

That’s been deprecated for quite some time now.

RFC 2818 - 3.1 Server Identity

If a subjectAltName extension of type dNSName is present, that MUST
be used as the identity. Otherwise, the (most specific) Common Name
field in the Subject field of the certificate MUST be used. Although
the use of the Common Name is existing practice, it is deprecated and
Certification Authorities are encouraged to use the dNSName instead.

RFC 6125 - 1.5 Overview of Recommendations

  • Move away from including and checking strings that look like
    domain names in the subject’s Common Name.

  • Move toward including and checking DNS domain names via the
    subjectAlternativeName extension designed for that purpose:
    dNSName.

RFC 6125 - 6.4.4 Checking of Common Names

As noted, a client MUST NOT seek a match for a reference identifier
of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
URI-ID, or any application-specific identifier types supported by the
client.

Try this instead:

openssl s_client -servername mastodon.local -connect mastodon.local:10443 </dev/null 2>/dev/null | openssl x509 -noout -text 2>/dev/null | grep DNS:
3 Likes

FYI gnutls-cli is a much nicer tool for testing than openssl s_client ...

$ gnutls-cli google.com
Processed 151 CA certificate(s).
Resolving 'google.com:443'...
Connecting to '2404:6800:400a:806::200e:443'...
- Certificate type: X.509
- Got a certificate list of 3 certificates.
- Certificate[0] info:
 - subject `CN=*.google.com', issuer `CN=WE2,O=Google Trust Services,C=US', serial 0x00b369230e77ac3bdd0ae77b6f4785eefb, EC/ECDSA key 256 bits, signed using ECDSA-SHA256, activated `2025-12-03 15:50:09 UTC', expires `2026-02-25 15:50:08 UTC', pin-sha256="h7hAH+TZRvd/3KRg71Iz0KyP+irrVdjt7AbhrxeL028="
	Public Key ID:
		sha1:9eea718bcf73bb52b66ffdfe69e0355d396288ef
		sha256:87b8401fe4d946f77fdca460ef5233d0ac8ffa2aeb55d8edec06e1af178bd36f
	Public Key PIN:
		pin-sha256:h7hAH+TZRvd/3KRg71Iz0KyP+irrVdjt7AbhrxeL028=

- Certificate[1] info:
 - subject `CN=WE2,O=Google Trust Services,C=US', issuer `CN=GTS Root R4,O=Google Trust Services LLC,C=US', serial 0x7ff32d6b409d15d5965b05873a7c72e0, EC/ECDSA key 256 bits, signed using ECDSA-SHA384, activated `2023-12-13 09:00:00 UTC', expires `2029-02-20 14:00:00 UTC', pin-sha256="vh78KSg1Ry4NaqGDV10w/cTb9VH3BQUZoCWNa93W/EY="
- Certificate[2] info:
 - subject `CN=GTS Root R4,O=Google Trust Services LLC,C=US', issuer `CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE', serial 0x7fe530bf331343bedd821610493d8a1b, EC/ECDSA key 384 bits, signed using RSA-SHA256, activated `2023-11-15 03:43:21 UTC', expires `2028-01-28 00:00:42 UTC', pin-sha256="mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c="
- Status: The certificate is trusted. 
- Description: (TLS1.3-X.509)-(ECDHE-X25519)-(ECDSA-SECP256R1-SHA256)-(AES-256-GCM)
- Session ID: C6:D5:3F:6C:EC:F6:61:CE:98:6B:FA:17:FF:03:50:53:7F:18:05:EE:B5:38:B8:D6:4F:4C:C0:16:60:19:EB:FA
- Options:
- Handshake was completed

- Simple Client Mode:
1 Like

Ohhh! Thanks. Makes sense and I didn’t check the SANs.

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