caddyserver/caddy · error

getting tls app: %v

Error message

getting tls app: %v

What it means

The http app's Provision first loads the tls app via ctx.App("tls"); if the tls app's own provisioning or validation fails (bad certificate config, invalid issuer, bad automation policy), the failure is wrapped as 'getting tls app'. The http app hard-depends on tls, so a broken TLS config breaks HTTP startup.

Source

Thrown at modules/caddyhttp/app.go:196

// CaddyModule returns the Caddy module information.
func (App) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "http",
		New: func() caddy.Module { return new(App) },
	}
}

// Provision sets up the app.
func (app *App) Provision(ctx caddy.Context) error {
	// store some references
	app.logger = ctx.Logger()
	app.ctx = ctx

	// provision TLS and events apps
	tlsAppIface, err := ctx.App("tls")
	if err != nil {
		return fmt.Errorf("getting tls app: %v", err)
	}
	app.tlsApp = tlsAppIface.(*caddytls.TLS)

	eventsAppIface, err := ctx.App("events")
	if err != nil {
		return fmt.Errorf("getting events app: %v", err)
	}

	repl := caddy.NewReplacer()

	// this provisions the matchers for each route,
	// and prepares auto HTTP->HTTPS redirects, and
	// is required before we provision each server
	err = app.automaticHTTPSPhase1(ctx, repl)
	if err != nil {
		return err
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Ignore the wrapper and read the nested cause after the colon — fix the tls-side problem it names.
  2. Run 'caddy validate' on the full config to surface the tls error directly.
  3. Common fixes: correct cert/key paths, valid issuer module names, well-formed automation policies.
  4. Bisect by removing tls customization (fall back to automatic HTTPS defaults) and re-adding piecewise.

Example fix

// before (caddyfile)
tls /etc/caddy/cert.pem /etc/caddy/key.pem  # key.pem path wrong

// after
tls /etc/caddy/cert.pem /etc/caddy/cert.key
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: confirm cert/key files referenced by the tls app exist and parse
for _, pair := range certPairs(cfg) {
    if err := checkPair(pair.Cert, pair.Key); err != nil {
        return err // report before caddy load wraps it
    }
}

Try / catch

if err := caddy.Validate(cfg); err != nil {
    if strings.Contains(err.Error(), "getting tls app") {
        // root cause is the nested tls error — fix tls config, not http
    }
    return err
}

Prevention

When it happens

Trigger: Any config where the tls app config is invalid: malformed automation policies, bad ACME issuer fields, unreadable certificate files via files loader, etc. — loaded indirectly while the http app provisions.

Common situations: TLS directives with wrong paths or PEM parse errors; issuer module typos; on-demand TLS misconfiguration; version changes to caddytls config schema. The error text says 'getting tls app' but the root cause is inside the tls app's config.

Understand the failure class

Related errors


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