caddyserver/caddy · info · caddy.APIError

no certificate authority configured with id: %s

Error message

no certificate authority configured with id: %s

What it means

A 404 caddy.APIError returned when the requested CA id is not configured in the running pki app and is not the default id (`local`). The admin API refuses to conjure arbitrary CAs on demand; only the default CA gets lazily provisioned. The message includes the exact id that was not found.

Source

Thrown at modules/caddypki/adminapi.go:201

	// Find the CA by ID, if PKI is configured
	var ca *CA
	var ok bool
	if a.pkiApp != nil {
		ca, ok = a.pkiApp.CAs[id]
	}

	// If we didn't find the CA, and PKI is not configured
	// then we'll either error out if the CA ID is not the
	// default. If the CA ID is the default, then we'll
	// provision it, because the user probably aims to
	// change their config to enable PKI immediately after
	// if they actually requested the local CA ID.
	if !ok {
		if id != DefaultCAID {
			return nil, caddy.APIError{
				HTTPStatus: http.StatusNotFound,
				Err:        fmt.Errorf("no certificate authority configured with id: %s", id),
			}
		}

		// Provision the default CA, which generates and stores a root
		// certificate in storage, if one doesn't already exist.
		ca = new(CA)
		err := ca.Provision(a.ctx, id, a.log)
		if err != nil {
			return nil, caddy.APIError{
				HTTPStatus: http.StatusInternalServerError,
				Err:        fmt.Errorf("failed to provision CA %s, %w", id, err),
			}
		}
	}

	return ca, nil
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. List configured CAs: GET /pki/ca only routes known ids — inspect the running config via GET /config/ to see pki.certificate_authorities keys
  2. Add the CA to config (pki app, certificate_authorities.<id>) and reload, then retry
  3. Use the default id `local`, which provisions on demand
  4. Fix the id typo — ids are case-sensitive

Example fix

# before: 'myca' not in config
curl http://localhost:2019/pki/ca/myca   # 404

# after: declare it, then query
cat caddy.json  # "pki": {"certificate_authorities": {"myca": {}}}
curl -X PUT http://localhost:2019/load -H 'Content-Type: application/json' -d @caddy.json
curl http://localhost:2019/pki/ca/myca
Defensive patterns

Strategy: validation

Validate before calling

// Compare requested id against configured CAs before calling:
func caExists(base, id string) bool {
    resp, err := http.Get(base + "/config/pki/certificate_authorities")
    if err != nil { return false }
    defer resp.Body.Close()
    var m map[string]json.RawMessage
    json.NewDecoder(resp.Body).Decode(&m)
    _, ok := m[id]
    return ok || id == "local"
}

Type guard

func isKnownCA(id string, configured map[string]bool) bool {
    return configured[id] || id == "local"
}

Try / catch

// 404 here is a config gap, not transient — do not retry:
if resp.StatusCode == 404 {
    return fmt.Errorf("CA %q not configured; add it under pki.certificate_authorities", id)
}

Prevention

When it happens

Trigger: GET /pki/ca/myca when the config's pki.certificate_authorities has no `myca` entry (or the pki app isn't configured at all). The lookup a.pkiApp.CAs[id] misses, id != DefaultCAID, and the 404 is returned.

Common situations: Querying a CA id defined in a different environment; typo in the id; the pki app config section was renamed/removed during a refactor; acme_server referencing a custom CA that isn't declared under pki.certificate_authorities.

Understand the failure class

Related errors


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