caddyserver/caddy · error

hostname appears in more than one automation policy, making

Error message

hostname appears in more than one automation policy, making certificate management ambiguous: %s

What it means

After consolidating identical automation policies, the adapter verifies no hostname appears in two different policies; otherwise certificate management (issuers, key type, on-demand, ...) would be ambiguous. It is an adapt-time convenience check of a constraint also enforced at provision time.

Source

Thrown at caddyconfig/httpcaddyfile/tlsapp.go:496

			if len(ap.Issuers) > 0 && ap.IssuersRaw == nil {
				for _, iss := range ap.Issuers {
					issuerName := iss.(caddy.Module).CaddyModule().ID.Name()
					ap.IssuersRaw = append(ap.IssuersRaw, caddyconfig.JSONModuleObject(iss, "module", issuerName, &warnings))
				}
			}
		}

		// consolidate automation policies that are the exact same
		tlsApp.Automation.Policies = consolidateAutomationPolicies(tlsApp.Automation.Policies)

		// ensure automation policies don't overlap subjects (this should be
		// an error at provision-time as well, but catch it in the adapt phase
		// for convenience)
		automationHostSet := make(map[string]struct{})
		for _, ap := range tlsApp.Automation.Policies {
			for _, s := range ap.SubjectsRaw {
				if _, ok := automationHostSet[s]; ok {
					return nil, warnings, fmt.Errorf("hostname appears in more than one automation policy, making certificate management ambiguous: %s", s)
				}
				automationHostSet[s] = struct{}{}
			}
		}

		// if nothing remains, remove any excess values to clean up the resulting config
		if len(tlsApp.Automation.Policies) == 0 {
			tlsApp.Automation.Policies = nil
		}
		if reflect.DeepEqual(tlsApp.Automation, new(caddytls.AutomationConfig)) {
			tlsApp.Automation = nil
		}
	}

	return tlsApp, warnings, nil
}

type acmeCapable interface{ GetACMEIssuer() *caddytls.ACMEIssuer }

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Make the TLS configuration for the duplicated hostname identical in every block, or consolidate it into one site block.
  2. Manage TLS for each hostname from exactly one config location.
  3. Adapt to JSON ('caddy adapt --pretty') and inspect apps.tls.automation.policies[].subjects to find the overlap.

Example fix

# before
example.com {
  tls internal
}
example.com:8443 {
  tls {
    key_type p256
  }
}

# after
example.com, example.com:8443 {
  tls {
    key_type p256
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# inspect consolidated policy subjects to find overlaps before provisioning
caddy adapt --config Caddyfile --adapter caddyfile --pretty | jq '.apps.tls.automation.policies[].subjects'

Prevention

When it happens

Trigger: Two automation policies with non-identical settings covering the same subject — e.g. 'example.com:443 { tls internal }' and 'example.com:8443 { tls { key_type p256 } }' produce two policies both containing example.com; similar overlaps via snippets defining tls settings imported for the same domain.

Common situations: Serving the same hostname on multiple ports with different tls settings; adding global or per-site tls options that repeat hostnames already covered elsewhere; policy shapes that consolidate differently after an upgrade.

Understand the failure class

Related errors


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