caddyserver/caddy · error
getting server identity credentials: %v
Error message
getting server identity credentials: %v
What it means
When the http config loader is configured with tls.use_server_identity, makeClient asks the Caddy context for the server's own identity certificate (the local PKI-installed leaf, via IdentityCredentials) to use as the client certificate. Failure to obtain it (local CA not provisioned, identity cert missing or unreadable) is wrapped with this message.
Source
Thrown at caddyconfig/httploader.go:182
}
}
return resp, err
}
func (hl HTTPLoader) makeClient(ctx caddy.Context) (*http.Client, error) {
client := &http.Client{
Timeout: time.Duration(hl.Timeout),
}
if hl.TLS != nil {
var tlsConfig *tls.Config
// client authentication
if hl.TLS.UseServerIdentity {
certs, err := ctx.IdentityCredentials(ctx.Logger())
if err != nil {
return nil, fmt.Errorf("getting server identity credentials: %v", err)
}
// See https://github.com/securego/gosec/issues/1054#issuecomment-2072235199
//nolint:gosec
tlsConfig = &tls.Config{Certificates: certs}
} else if hl.TLS.ClientCertificateFile != "" && hl.TLS.ClientCertificateKeyFile != "" {
cert, err := tls.LoadX509KeyPair(hl.TLS.ClientCertificateFile, hl.TLS.ClientCertificateKeyFile)
if err != nil {
return nil, err
}
//nolint:gosec
tlsConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
}
// trusted server certs
if len(hl.TLS.RootCAPEMFiles) > 0 {
rootPool := x509.NewCertPool()
for _, pemFile := range hl.TLS.RootCAPEMFiles {
pemData, err := os.ReadFile(pemFile)View on GitHub (pinned to 50e54ee279)
Solutions
- Verify Caddy's storage/data directory is writable and persistent (same volume across restarts).
- Run 'caddy trust' / start Caddy once so the local PKI and identity cert get provisioned.
- Check file permissions on the storage directory for the Caddy user.
- If mTLS with a custom CA is intended instead, use client_certificate_file/client_certificate_key_file rather than use_server_identity.
Example fix
# before
http https://cfg.internal/config.json {
tls {
use_server_identity
}
}
# after (mTLS with explicit client cert when identity creds are unavailable)
http https://cfg.internal/config.json {
tls {
client_certificate_file /etc/caddy/client.crt
client_certificate_key_file /etc/caddy/client.key
root_ca /etc/caddy/ca.pem
}
} Defensive patterns
Strategy: validation
Validate before calling
# confirm the local PKI identity exists and is readable
ls -l "${XDG_DATA_HOME:-$HOME/.local/share}/caddy/pki/authorities/local" 2>/dev/null || echo 'no local PKI: run caddy trust / start once' Prevention
- Persist Caddy's storage directory across restarts/containers.
- Run 'caddy trust' once on fresh hosts before enabling use_server_identity.
- Prefer explicit client cert files when the local PKI is unavailable.
When it happens
Trigger: 'use_server_identity' set on the http loader while ctx.IdentityCredentials fails — local PKI not yet provisioned on a fresh host, storage directory missing/unreadable, or the identity certificate absent (e.g. non-persistent container volume).
Common situations: First run with a custom or read-only XDG_DATA_HOME; containers missing the persisted storage volume so identity certs never exist; permission changes on the data directory after initial provisioning.
Related errors
- problem calling http loader url: %v
- failed reading ca cert: %v
- provisioning default internal automation policy: %v
- cannot enable remote admin without a certificate cache; conf
- provisioning remote admin endpoint: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/c7ab7949813f2ee5.
Report an issue: GitHub.