caddyserver/caddy · error

provisioning default internal automation policy: %v

Error message

provisioning default internal automation policy: %v

What it means

If any name in the 'automate' list does not qualify for a public certificate (internal names like .local, IP addresses, unqualified hostnames — see certmagic.SubjectQualifiesForPublicCert), Caddy synthesizes a default internal automation policy with issuer {"module":"internal"} and provisions it. Failure of that internal issuer provisioning produces this error. Because the policy is hard-coded, failures usually stem from the PKI app or storage, not user config.

Source

Thrown at modules/caddytls/tls.go:310

	}
	t.Automation.defaultPublicAutomationPolicy = new(AutomationPolicy)
	err = t.Automation.defaultPublicAutomationPolicy.Provision(t)
	if err != nil {
		return fmt.Errorf("provisioning default public automation policy: %v", err)
	}
	for n := range t.automateNames {
		// if any names specified by the "automate" loader do not qualify for a public
		// certificate, we should initialize a default internal automation policy
		// (but we don't want to do this unnecessarily, since it may prompt for password!)
		if certmagic.SubjectQualifiesForPublicCert(n) {
			continue
		}
		t.Automation.defaultInternalAutomationPolicy = &AutomationPolicy{
			IssuersRaw: []json.RawMessage{json.RawMessage(`{"module":"internal"}`)},
		}
		err = t.Automation.defaultInternalAutomationPolicy.Provision(t)
		if err != nil {
			return fmt.Errorf("provisioning default internal automation policy: %v", err)
		}
		break
	}
	for i, ap := range t.Automation.Policies {
		err := ap.Provision(t)
		if err != nil {
			return fmt.Errorf("provisioning automation policy %d: %v", i, err)
		}
	}

	// run replacer on ask URL (for environment variables) -- return errors to prevent surprises (#5036)
	if t.Automation != nil && t.Automation.OnDemand != nil && t.Automation.OnDemand.Ask != "" {
		t.Automation.OnDemand.Ask, err = repl.ReplaceOrErr(t.Automation.OnDemand.Ask, true, true)
		if err != nil {
			return fmt.Errorf("preparing 'ask' endpoint: %v", err)
		}
		perm := PermissionByHTTP{
			Endpoint: t.Automation.OnDemand.Ask,

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped error to identify the failing sub-step (issuer loading, storage, certmagic config)
  2. If internal names are unintended, remove them from the automate list
  3. For intentional internal names, make sure the pki app is available/default so the internal issuer can build its CA
  4. Check storage writability (the internal issuer persists CA state)

Example fix

// before
{"certificates": {"automate": ["myserver.local"]}}
// after (explicit policy for internal names, clearer errors)
{"automation": {"policies": [{"subjects": ["myserver.local"], "issuers": [{"module": "internal"}]}]}}
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/caddyserver/certmagic"

for _, n := range automateNames {
	if !certmagic.SubjectQualifiesForPublicCert(n) {
		log.Printf("%s needs an explicit internal-issuer policy", n)
	}
}

Prevention

When it happens

Trigger: automate list contains 'localhost', '127.0.0.1', 'myserver.local', or a bare hostname; the synthesized policy's InternalIssuer Provision then fails — typically when the PKI app or certmagic storage is in a bad state, or in tests where the pki app is absent.

Common situations: Dev/test configs managing internal names; configs where the pki app was explicitly emptied; storage errors writing the internal CA intermediate.

Related errors


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