From 3a32167c277fb76c3592282962a3984f5105371a Mon Sep 17 00:00:00 2001 From: Faiyaz Rahman Date: Wed, 9 Sep 2026 16:12:38 +0600 Subject: [PATCH] docs: note that validate cannot run against a running instance caddy validate provisions modules for real. acme_server opens a database that only one process can hold at a time, so validating while Caddy runs times out even though the config is fine. Explain this in the caddy validate section and add a short note on the acme_server directive pointing back to it. --- src/docs/markdown/caddyfile/directives/acme_server.md | 2 ++ src/docs/markdown/command-line.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/docs/markdown/caddyfile/directives/acme_server.md b/src/docs/markdown/caddyfile/directives/acme_server.md index 3da49fff..766badb9 100644 --- a/src/docs/markdown/caddyfile/directives/acme_server.md +++ b/src/docs/markdown/caddyfile/directives/acme_server.md @@ -8,6 +8,8 @@ An embedded [ACME protocol](https://tools.ietf.org/html/rfc8555) server handler. When enabled, requests matching the path `/acme/*` will be handled by the ACME server. +The ACME server keeps a database on disk, and only one process can have it open at a time. This means [`caddy validate`](/docs/command-line#caddy-validate) fails with a database timeout if it is run while Caddy is already serving this config, because validating provisions the modules for real. Validate before starting Caddy, or use [`caddy reload`](/docs/command-line#caddy-reload) to check a config against the running instance: reload provisions the new config within the running process, so it does not contend for the database. If provisioning fails, the active config keeps running; if it succeeds, the new config is applied. + ## Client configuration diff --git a/src/docs/markdown/command-line.md b/src/docs/markdown/command-line.md index 27002d3a..c7d56ef7 100644 --- a/src/docs/markdown/command-line.md +++ b/src/docs/markdown/command-line.md @@ -688,6 +688,8 @@ Similarly to `caddy upgrade`, replaces the current Caddy binary with the latest Validates a configuration file, then exits. This command deserializes the config, then loads and provisions all of its modules as if to start the config, but the config is not actually started. This exposes errors in a configuration that arise during loading or provisioning phases and is a stronger error check than merely serializing a config as JSON. +Because modules are provisioned for real, this command is best run before starting Caddy. Some modules acquire exclusive resources while being provisioned, and a second Caddy process cannot acquire them while a running instance holds them. For example, the [`acme_server`](/docs/caddyfile/directives/acme_server) directive opens a database that only one process can have open at a time, so validating a config that uses it while Caddy is already running fails with a database timeout, even though the config itself is fine. To check a config against a running instance, use [`caddy reload`](#caddy-reload) instead: it provisions the new config within the running process, so it does not contend with the running instance for those resources. If provisioning fails, the active config keeps running; if it succeeds, the new config is applied. + `--config` is the config file to validate. If `-`, the config is read from stdin. Default is the `Caddyfile` in the current directory, if any. `--adapter` is the name of the config adapter to use. This flag is not necessary if the `--config` filename starts with `Caddyfile` or ends with `.caddyfile` which assumes the `caddyfile` adapter. Otherwise, this flag is required if the provided config file is not in Caddy's native JSON format.