caddyserver/caddy · error
unrecognized config adapter '%s'
Error message
unrecognized config adapter '%s'
What it means
Returned when the subtype of the Content-Type does not match any registered config adapter (GetAdapter returns nil). The adapter name is taken from the part after the slash: text/caddyfile looks up 'caddyfile'. If that adapter is not compiled into the binary or does not exist, the request fails with HTTP 400.
Source
Thrown at caddyconfig/load.go:206
HTTPStatus: http.StatusBadRequest,
Err: fmt.Errorf("invalid Content-Type: %v", err),
}
}
// if already JSON, no need to adapt
if strings.HasSuffix(ct, "/json") {
return body, nil, nil
}
// adapter name should be suffix of MIME type
_, adapterName, slashFound := strings.Cut(ct, "/")
if !slashFound {
return nil, nil, fmt.Errorf("malformed Content-Type")
}
cfgAdapter := GetAdapter(adapterName)
if cfgAdapter == nil {
return nil, nil, fmt.Errorf("unrecognized config adapter '%s'", adapterName)
}
result, warnings, err := cfgAdapter.Adapt(body, nil)
if err != nil {
return nil, nil, fmt.Errorf("adapting config using %s adapter: %v", adapterName, err)
}
return result, warnings, nil
}
var bufPool = sync.Pool{
New: func() any {
return new(bytes.Buffer)
},
}
View on GitHub (pinned to 50e54ee279)
Solutions
- Check available adapters: caddy list-modules --packages caddy.config_adapters or caddy adapt --adapter
- Use the official distribution or rebuild with xcaddy including the adapter module
- Fix typos in the Content-Type subtype (e.g. text/caddyfile, not text/caddy-file)
- Send application/json to skip adapters entirely when the body is already Caddy JSON
Example fix
# before curl -X POST http://localhost:2019/load -H 'Content-Type: text/caddy-file' -d @Caddyfile # after curl -X POST http://localhost:2019/load -H 'Content-Type: text/caddyfile' -d @Caddyfile
Defensive patterns
Strategy: validation
Validate before calling
// confirm the adapter exists before using it
func adapterExists(name string) bool {
for _, a := range caddyconfig.RegisteredAdapters() { // or parse `caddy list-modules` output
if a == name { return true }
}
return false
}
if !adapterExists(adapter) { return fmt.Errorf("adapter %q not in this build; rebuild with xcaddy", adapter) } Try / catch
if resp.StatusCode == http.StatusBadRequest && strings.Contains(bodyText, "unrecognized config adapter") {
return errors.New("adapter missing from build — check caddy list-modules --packages caddy.config_adapters")
} Prevention
- In CI, assert the adapter list of your custom build matches the config formats you deploy
- Standardize on text/caddyfile (full distributions) or application/json to avoid adapter lookup entirely
When it happens
Trigger: Content-Type: text/caddyfile sent to a custom Caddy build without the caddyfile adapter; typos like text/caddyfil or text/jsonc; using a third-party adapter name (e.g. text/hcl) in a build that lacks the plugin.
Common situations: Minimal custom builds (built from source without modules/caddyfile) that still expose the admin API; version drift where an adapter was renamed; scripts written against full distributions but deployed against slim builds.
Related errors
- invalid Content-Type: %v
- adapting config using %s adapter: %v
- reading request body: %v
- loading config: %v
- malformed Content-Type
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/120bff0f9c0a667d.
Report an issue: GitHub.