caddyserver/caddy · error
CA ID is required (use 'local' for the default CA)
Error message
CA ID is required (use 'local' for the default CA)
What it means
Returned at the very start of CA.Provision when the id argument is empty — every CA must have an identifier, and the default is `local`. The id is used for the logger name (ca.<id>), storage namespacing, and admin API paths, so an empty one is rejected outright. Users normally hit this via a config that declares a CA with an empty/missing id, or by calling Provision programmatically without an id.
Source
Thrown at modules/caddypki/ca.go:105
storage certmagic.Storage
root *x509.Certificate
interChain []*x509.Certificate
interKey crypto.Signer
mu *sync.RWMutex
rootCertPath string // mainly used for logging purposes if trusting
log *zap.Logger
ctx caddy.Context
}
// Provision sets up the CA.
func (ca *CA) Provision(ctx caddy.Context, id string, log *zap.Logger) error {
ca.mu = new(sync.RWMutex)
ca.log = log.Named("ca." + id)
ca.ctx = ctx
if id == "" {
return fmt.Errorf("CA ID is required (use 'local' for the default CA)")
}
ca.mu.Lock()
ca.ID = id
ca.mu.Unlock()
if ca.StorageRaw != nil {
val, err := ctx.LoadModule(ca, "StorageRaw")
if err != nil {
return fmt.Errorf("loading storage module: %v", err)
}
cmStorage, err := val.(caddy.StorageConverter).CertMagicStorage()
if err != nil {
return fmt.Errorf("creating storage configuration: %v", err)
}
ca.storage = cmStorage
}
if ca.storage == nil {
ca.storage = ctx.Storage()View on GitHub (pinned to 50e54ee279)
Solutions
- Give the CA a non-empty id — or simply remove the empty entry to use the default `local` CA
- In JSON, the id is the map key under pki.certificate_authorities; make sure it is a real value
- If embedding Caddy, pass a concrete id: ca.Provision(ctx, "local", logger)
- Validate config with `caddy validate` before loading
Example fix
// before (JSON)
"pki": { "certificate_authorities": { "": {} } }
// after
"pki": { "certificate_authorities": { "local": {} } } Defensive patterns
Strategy: validation
Validate before calling
// Validate CA ids in generated config before loading:
func validateCAIDs(cas map[string]json.RawMessage) error {
for id := range cas {
if strings.TrimSpace(id) == "" {
return errors.New("pki.certificate_authorities has an empty CA id")
}
}
return nil
} Type guard
func validCAID(id string) bool { return strings.TrimSpace(id) != "" } Prevention
- Use `local` unless multiple CAs are needed
- Template guards: skip CA entries whose id variable is unset
- Run `caddy validate` on rendered configs in CI
When it happens
Trigger: JSON config with "pki": {"certificate_authorities": {"": {}}} (empty key), a Go program embedding Caddy that calls ca.Provision(ctx, "", logger), or config tooling that strips the id when generating the pki section. Note this is the CA-level id, not the common name fields.
Common situations: YAML/JSON templating that renders an empty CA key when a variable is unset; automated config generation inserting a placeholder CA; refactors that moved the id into the wrong field (e.g. putting it in name instead of the map key).
Related errors
- acme challenge %q is not supported
- intermediate certificate lifetime must be less than actual r
- parsing listener address: %v
- must be exactly one listener address; cannot listen on: %s
- indexing config: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/913f0043cace474a.
Report an issue: GitHub.