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

  1. Make the ids match exactly: define the CA under pki { ca <id> } and reference the identical <id> from internal issuers
  2. 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)
  3. Check for typos and case differences between the CA definition and its reference
  4. 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

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

Related errors


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