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

  1. Give the CA a non-empty id — or simply remove the empty entry to use the default `local` CA
  2. In JSON, the id is the map key under pki.certificate_authorities; make sure it is a real value
  3. If embedding Caddy, pass a concrete id: ca.Provision(ctx, "local", logger)
  4. 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

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


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/913f0043cace474a. Report an issue: GitHub.