{"record":{"id":"9650220223711b03","repo":"caddyserver/caddy","slug":"invalid-content-type-v","errorCode":null,"errorMessage":"invalid Content-Type: %v","messagePattern":"invalid Content-Type: (.+?)","errorType":"http","errorClass":"caddy.APIError","httpStatus":400,"severity":"error","filePath":"caddyconfig/load.go","lineNumber":189,"sourceCode":"\t}\n\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\treturn json.NewEncoder(w).Encode(out)\n}\n\n// adaptByContentType adapts body to Caddy JSON using the adapter specified by contentType.\n// If contentType is empty or ends with \"/json\", the input will be returned, as a no-op.\nfunc adaptByContentType(contentType string, body []byte) ([]byte, []Warning, error) {\n\t// assume JSON as the default\n\tif contentType == \"\" {\n\t\treturn body, nil, nil\n\t}\n\n\tct, _, err := mime.ParseMediaType(contentType)\n\tif err != nil {\n\t\treturn nil, nil, caddy.APIError{\n\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\tErr:        fmt.Errorf(\"invalid Content-Type: %v\", err),\n\t\t}\n\t}\n\n\t// if already JSON, no need to adapt\n\tif strings.HasSuffix(ct, \"/json\") {\n\t\treturn body, nil, nil\n\t}\n\n\t// adapter name should be suffix of MIME type\n\t_, adapterName, slashFound := strings.Cut(ct, \"/\")\n\tif !slashFound {\n\t\treturn nil, nil, fmt.Errorf(\"malformed Content-Type\")\n\t}\n\n\tcfgAdapter := GetAdapter(adapterName)\n\tif cfgAdapter == nil {\n\t\treturn nil, nil, fmt.Errorf(\"unrecognized config adapter '%s'\", adapterName)\n\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/caddyconfig/load.go#L171-L207","documentation":"Returned with HTTP 400 when the request's Content-Type header cannot be parsed by Go's mime.ParseMediaType on /load or /adapt. The header must be a valid MIME type with optional parameters, e.g. 'text/caddyfile; charset=utf-8'. Garbage like 'caddyfile' alone, empty type with parameters (';charset=utf-8'), or stray characters cause the parse to fail.","triggerScenarios":"Setting Content-Type: caddyfile (no slash, no type/subtype structure); Content-Type with malformed parameters like 'text/caddyfile;;'; duplicated headers producing an invalid joined value; clients sending 'Content-Type: ' with trailing junk.","commonSituations":"Scripts that set the adapter name directly as the Content-Type instead of text/<adapter>; copy-paste of header values with smart quotes or whitespace; HTTP libraries auto-appending broken charset parameters.","solutions":["Use a well-formed MIME type: Content-Type: text/caddyfile (the part after the slash names the adapter)","Omit Content-Type entirely if the body is already Caddy JSON (it defaults to JSON)","End JSON types with /json, e.g. application/json, to skip adaptation"],"exampleFix":"# before\ncurl -X POST http://localhost:2019/load -H 'Content-Type: caddyfile' -d @Caddyfile\n# after\ncurl -X POST http://localhost:2019/load -H 'Content-Type: text/caddyfile' -d @Caddyfile","handlingStrategy":"validation","validationCode":"// validate the header before sending\nfunc validCT(ct string) bool {\n    if ct == \"\" { return true } // JSON default\n    t, _, err := mime.ParseMediaType(ct)\n    return err == nil && strings.Contains(t, \"/\")\n}\nif !validCT(ct) { return fmt.Errorf(\"bad Content-Type %q; use e.g. text/caddyfile\", ct) }","typeGuard":null,"tryCatchPattern":"if resp.StatusCode == http.StatusBadRequest && strings.Contains(bodyText, \"invalid Content-Type\") {\n    // fix header client-side; retrying unchanged will always fail\n    req.Header.Set(\"Content-Type\", \"application/json\")\n}","preventionTips":["Only use mime.ParseMediaType-legal values: type/subtype with optional ;key=value params","Keep adapter names in the subtype (text/caddyfile), never as the whole header"],"tags":["admin-api","http-headers","content-type","http-400"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}