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

  1. Check available adapters: caddy list-modules --packages caddy.config_adapters or caddy adapt --adapter
  2. Use the official distribution or rebuild with xcaddy including the adapter module
  3. Fix typos in the Content-Type subtype (e.g. text/caddyfile, not text/caddy-file)
  4. 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

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


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