{"record":{"id":"6a7db9e96dc1f524","repo":"caddyserver/caddy","slug":"got-http-d","errorCode":null,"errorMessage":"got HTTP %d","messagePattern":"got HTTP (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/certmanagers.go","lineNumber":168,"sourceCode":"\t}\n\tparsed.RawQuery = qs.Encode()\n\n\treq, err := http.NewRequestWithContext(hcg.ctx, http.MethodGet, parsed.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := http.DefaultClient.Do(req) //nolint:gosec // SSRF false positive... request URI comes from config\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode == http.StatusNoContent {\n\t\t// endpoint is not managing certs for this handshake\n\t\treturn nil, nil\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"got HTTP %d\", resp.StatusCode)\n\t}\n\n\tbodyBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading response body: %v\", err)\n\t}\n\n\tcert, err := tlsCertFromCertAndKeyPEMBundle(bodyBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cert, nil\n}\n\n// UnmarshalCaddyfile deserializes Caddyfile tokens into ts.\n//\n//\t... http <url>","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/certmanagers.go#L150-L186","documentation":"Returned at handshake time by HTTPCertGetter.GetCertificate when the remote certificate endpoint answered with a status code other than 200 or 204. 204 is treated as 'this endpoint is not managing certs for this handshake' and returns nil; any other non-200 status is an error because the body cannot be trusted to contain a valid PEM bundle.","triggerScenarios":"The configured URL returns 404 (no cert for the requested SNI/serial), 401/403 (auth failure), 500 (upstream bug), or a redirect chain ending in a non-200. The request includes query params for the ClientHello (serial, SNI, cipher suites), so endpoints that key on those params can 404 legitimately.","commonSituations":"Cert management service does not have a certificate issued yet for the domain; auth token expired or missing on the getter side; the endpoint route changed after an upgrade of the cert service; a proxy in front returns 502/503.","solutions":["Reproduce the handshake request manually (include the serial/SNI query params) against the URL and inspect the status code and body","If the endpoint genuinely has no cert for this SNI yet, return 204 instead of 404 so the next getter in the chain can be tried","Fix auth/proxy issues: verify tokens, upstream health, and that the route still exists","Check Caddy's logs for which URL and handshake triggered it, since the error carries only the status number"],"exampleFix":"// before (cert endpoint handler)\nfunc certHandler(w http.ResponseWriter, r *http.Request) {\n\tcert := lookup(r.URL.Query().Get(\"server_name\"))\n\tif cert == nil {\n\t\thttp.NotFound(w, r) // 404 -> handshake error in Caddy\n\t\treturn\n\t}\n\tw.Write(cert)\n}\n\n// after\nfunc certHandler(w http.ResponseWriter, r *http.Request) {\n\tcert := lookup(r.URL.Query().Get(\"server_name\"))\n\tif cert == nil {\n\t\tw.WriteHeader(http.StatusNoContent) // 204: try next source\n\t\treturn\n\t}\n\tw.Write(cert)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// If wrapping tls.get_certificate.http behind your own getter:\ncert, err := hcg.GetCertificate(ctx, hello)\nif err != nil {\n\tif strings.HasPrefix(err.Error(), \"got HTTP \") {\n\t\t// endpoint responded but not usefully; log and rethrow or fall through\n\t\tlog.Printf(\"cert endpoint status: %v\", err)\n\t}\n\treturn nil, err\n}","preventionTips":["Make your cert endpoint return 204 (not 404) when it has no cert for a handshake, so chains can continue","Health-check the cert endpoint independently of handshakes to catch auth/proxy failures early","Keep the URL pinned to a stable route; avoid redirects on the cert path"],"tags":["caddy","tls","http","certificates","status-code","network"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}