caddyserver/caddy · error

getting CA %s: %v

Error message

getting CA %s: %v

What it means

While provisioning a pki_root CA pool, pki.GetCA(ctx, caID) either returned an error or a nil CA for one of the configured authority IDs. GetCA looks up (and lazily creates) authorities inside the PKI app; failure means the ID could not be resolved to a usable CA in the current configuration.

Source

Thrown at modules/caddytls/capools.go:241

	return caddy.ModuleInfo{
		ID: "tls.ca_pool.source.pki_root",
		New: func() caddy.Module {
			return new(PKIRootCAPool)
		},
	}
}

// Loads the PKI app and load the root certificates into the certificate pool
func (p *PKIRootCAPool) Provision(ctx caddy.Context) error {
	pkiApp, err := ctx.AppIfConfigured("pki")
	if err != nil {
		return fmt.Errorf("pki_root CA pool requires that a PKI app is configured: %v", err)
	}
	pki := pkiApp.(*caddypki.PKI)
	for _, caID := range p.Authority {
		c, err := pki.GetCA(ctx, caID)
		if err != nil || c == nil {
			return fmt.Errorf("getting CA %s: %v", caID, err)
		}
		p.ca = append(p.ca, c)
	}

	caPool := x509.NewCertPool()
	var certs []*x509.Certificate
	for _, ca := range p.ca {
		rootCert := ca.RootCertificate()
		if rootCert == nil {
			return fmt.Errorf("CA %s has no root certificate", ca.ID)
		}
		caPool.AddCert(rootCert)
		certs = append(certs, rootCert)
	}
	p.pool = caPool
	p.certs = certs

	return nil

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Check the exact `ca` IDs in the trust_pool against the IDs declared in the global `pki` option block and fix any typo.
  2. If using JSON config, confirm apps.pki.cas contains an entry whose key matches the referenced caID.
  3. Run `caddy adapt --config Caddyfile --adapter caddyfile` and inspect the generated pki app to see which CA IDs actually exist.

Example fix

# before
{
  pki {
    ca my_ca { name "My CA" }
  }
}
example.com {
  tls { client_auth { trust_pool pki_root { ca my-ca } } }
}

# after
{
  pki {
    ca my_ca { name "My CA" }
  }
}
example.com {
  tls { client_auth { trust_pool pki_root { ca my_ca } } }
}
Defensive patterns

Strategy: validation

Validate before calling

// verify every referenced authority id exists in the adapted JSON pki app
import "encoding/json"

func validateCARIDs(cfgJSON []byte, referenced []string) error {
	var cfg struct {
		Apps struct {
			PKI struct {
				CAs map[string]json.RawMessage `json:"cas"`
			} `json:"pki"`
		} `json:"apps"`
	}
	if err := json.Unmarshal(cfgJSON, &cfg); err != nil {
		return err
	}
	for _, id := range referenced {
		if _, ok := cfg.Apps.PKI.CAs[id]; !ok {
			return fmt.Errorf("CA id %q not defined in pki app", id)
		}
	}
	return nil
}

Prevention

When it happens

Trigger: Listing a `ca <id>` under `trust_pool pki_root` whose ID does not exist and cannot be created in the pki app (e.g. it was declared under a different app instance, has invalid characters, or the pki app was provisioned in a separate config scope).

Common situations: Typos in the CA id; referencing a CA defined in a different Caddy instance or config snippet that was not merged; renaming a CA in the pki block without updating the trust pool references.

Related errors


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