caddyserver/caddy · error
no certificate authority configured with id: %s
Error message
no certificate authority configured with id: %s
What it means
Returned by PKI.GetCA (modules/caddypki/pki.go:133) when a caller asks for a CA by an ID that is not configured. Only the default CA ID ('local') gets lazy auto-provisioning; any other unknown ID is rejected immediately.
Source
Thrown at modules/caddypki/pki.go:133
}
return nil
}
// Stop stops the PKI app.
func (p *PKI) Stop() error {
return nil
}
// GetCA retrieves a CA by ID. If the ID is the default
// CA ID, and it hasn't been provisioned yet, it will
// be provisioned.
func (p *PKI) GetCA(ctx caddy.Context, id string) (*CA, error) {
ca, ok := p.CAs[id]
if !ok {
// for anything other than the default CA ID, error out if it wasn't configured
if id != DefaultCAID {
return nil, fmt.Errorf("no certificate authority configured with id: %s", id)
}
// for the default CA ID, provision it, because we want it to "just work"
err := p.ProvisionDefaultCA(ctx)
if err != nil {
return nil, fmt.Errorf("failed to provision default CA: %s", err)
}
ca = p.CAs[id]
}
return ca, nil
}
// Interface guards
var (
_ caddy.Provisioner = (*PKI)(nil)
_ caddy.App = (*PKI)(nil)
)View on GitHub (pinned to 50e54ee279)
Solutions
- Make the ids match exactly: define the CA under pki { ca <id> } and reference the identical <id> from internal issuers
- If you only need a custom internal CA, add an explicit pki app block declaring it instead of relying on auto-creation (only 'local' is implicit)
- Check for typos and case differences between the CA definition and its reference
- As a fallback, remove the custom id to use the default 'local' CA
Example fix
# before: referenced CA was never defined
example.com {
tls {
issuance internal {
ca my_intermediate
}
}
}
# after: define it with the exact same id
{
pki {
ca my_intermediate {
name "My Intermediate CA"
}
}
}
example.com {
tls {
issuance internal {
ca my_intermediate
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// programmatically: check the CA exists before requesting it
tlsApp := ctx.App("tls")
pkiApp := tlsApp.(*caddytls.TLS) // ... obtain *pki.PKI via ctx.App("pki")
if _, ok := pkiApp.CAs["my_intermediate"]; !ok {
return fmt.Errorf("CA 'my_intermediate' must be declared in the pki app before use")
} Type guard
// config-level guard: grep that every referenced ca id is defined
// Caddyfile:
// defined: pki { ca <id> { ... } }
// referenced: issuance internal { ca <id> }
// ensure the sets match exactly (case-sensitive) Try / catch
ca, err := p.GetCA(ctx, id)
if err != nil {
if strings.Contains(err.Error(), "no certificate authority configured") {
// typo or missing pki block: declare the CA or fix the reference
return nil, fmt.Errorf("check pki app config: %w", err)
}
return nil, err
} Prevention
- Keep CA ids in one place (snippets/variables) and reference them everywhere else
- Lint configs: extract all `ca <id>` references and all `pki { ca <id> }` definitions and diff the lists
- Remember CA ids are case-sensitive and only 'local' is auto-provisioned
When it happens
Trigger: Referencing a CA id in configuration that does not exist in the pki app - e.g. tls issuance internal { ca my_ca } or an internal issuer referencing 'intermediate_ca' while the pki app defines no CA with that id (typo, different name, or the pki app not configured at all so only 'local' exists).
Common situations: Renaming a CA in the pki block but not in the tls/issuer reference (or vice versa); assuming a custom CA id is auto-created; copy-pasting configs between sites where the pki app section was dropped; case-sensitive id mismatches (MyCA vs myca).
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- provisioning CA '%s': %v
- pki_root CA pool requires that a PKI app is configured: %v
- getting CA %s: %v
- pki_intermediate CA pool requires that a PKI app is configur
- provisioning default internal automation policy: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/a7064a3e54dd1c09.
Report an issue: GitHub.