caddyserver/caddy · error

provision %s: %v

Error message

provision %s: %v

What it means

LoadModuleByID calls Provision(ctx) on modules implementing the Provisioner interface so they can set themselves up (resolve dependencies, allocate clients). Any error returned is wrapped as 'provision %s: %v' with the ModuleInfo string identifying the module. The inner error text is the module's own and is the actual diagnosis.

Source

Thrown at context.go:436

				ctx.cfg.failedApps[id] = err
			}
		}()
	}

	ctx.ancestry = append(ctx.ancestry, val)

	if prov, ok := val.(Provisioner); ok {
		err = prov.Provision(ctx)
		if err != nil {
			// incomplete provisioning could have left state
			// dangling, so make sure it gets cleaned up
			if cleanerUpper, ok := val.(CleanerUpper); ok {
				err2 := cleanerUpper.Cleanup()
				if err2 != nil {
					err = fmt.Errorf("%v; additionally, cleanup: %v", err, err2)
				}
			}
			return nil, fmt.Errorf("provision %s: %v", modInfo, err)
		}
	}

	if validator, ok := val.(Validator); ok {
		err = validator.Validate()
		if err != nil {
			// since the module was already provisioned, make sure we clean up
			if cleanerUpper, ok := val.(CleanerUpper); ok {
				err2 := cleanerUpper.Cleanup()
				if err2 != nil {
					err = fmt.Errorf("%v; additionally, cleanup: %v", err, err2)
				}
			}
			return nil, fmt.Errorf("%s: invalid configuration: %v", modInfo, err)
		}
	}

	ctx.moduleInstances[id] = append(ctx.moduleInstances[id], val)

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Identify the module from the ModuleInfo text in the error and read the inner error message — it states what provisioning could not do
  2. Correct the module's config per its documented requirements (required fields, allowed values)
  3. Check environmental prerequisites: storage permissions, reachable endpoints, env vars referenced with {env.*} placeholders
  4. Search the module's source for the returned error string to understand the exact condition

Example fix

// before
{ "handler": "reverse_proxy", "upstream": "localhost:8080" } // wrong field
// after
{ "handler": "reverse_proxy", "upstreams": [ { "dial": "localhost:8080" } ] }
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := ctx.LoadModuleByID(id, raw); err != nil {
    var msg string
    if unwrapped := errors.Unwrap(err); unwrapped != nil { msg = unwrapped.Error() } else { msg = err.Error() }
    return fmt.Errorf("module %s provisioning failed: %s", id, msg)
}

Prevention

When it happens

Trigger: A module's Provision returns an error — invalid option combinations, missing required config, failed dependency lookup via ctx.App/ctx.LoadModule, environment problems (unreachable endpoint, bad credentials referenced at provision time).

Common situations: TLS/ACME modules failing on bad issuer config; plugins requiring non-nil fields that JSON left empty; Provision calling ctx.App for an app that itself failed to provision; permission errors opening storage paths.

Related errors


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