{"record":{"id":"fed2ca5ac88ccade","repo":"caddyserver/caddy","slug":"decoding-api-response-v","errorCode":null,"errorMessage":"decoding API response: %v","messagePattern":"decoding API response: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddytls/acmeissuer.go","lineNumber":402,"sourceCode":"\n\tresp, err := http.DefaultClient.Do(req) //nolint:gosec // no SSRF since URL is from trusted config\n\tif err != nil {\n\t\treturn nil, acct, fmt.Errorf(\"performing EAB credentials request: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tvar result struct {\n\t\tSuccess bool `json:\"success\"`\n\t\tError   struct {\n\t\t\tCode int    `json:\"code\"`\n\t\t\tType string `json:\"type\"`\n\t\t} `json:\"error\"`\n\t\tEABKID     string `json:\"eab_kid\"`\n\t\tEABHMACKey string `json:\"eab_hmac_key\"`\n\t}\n\terr = json.NewDecoder(resp.Body).Decode(&result)\n\tif err != nil {\n\t\treturn nil, acct, fmt.Errorf(\"decoding API response: %v\", err)\n\t}\n\tif result.Error.Code != 0 {\n\t\t// do this check first because ZeroSSL's API returns 200 on errors\n\t\treturn nil, acct, fmt.Errorf(\"failed getting EAB credentials: HTTP %d: %s (code %d)\",\n\t\t\tresp.StatusCode, result.Error.Type, result.Error.Code)\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, acct, fmt.Errorf(\"failed getting EAB credentials: HTTP %d\", resp.StatusCode)\n\t}\n\n\tif c := iss.logger.Check(zapcore.InfoLevel, \"generated EAB credentials\"); c != nil {\n\t\tc.Write(zap.String(\"key_id\", result.EABKID))\n\t}\n\n\treturn &acme.EAB{\n\t\tKeyID:  result.EABKID,\n\t\tMACKey: result.EABHMACKey,\n\t}, acct, nil","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddytls/acmeissuer.go#L384-L420","documentation":"ZeroSSL's EAB endpoint returned a body that could not be JSON-decoded into the expected {success, error, eab_kid, eab_hmac_key} structure. The request itself succeeded (status received), but the payload was not valid JSON — e.g. an HTML error page from a proxy, an empty body, or truncated response.","triggerScenarios":"A transparent proxy or captive portal intercepting HTTPS and returning HTML; ZeroSSL returning a malformed/truncated response; a response body in an unexpected format from an API version change.","commonSituations":"Corporate MITM proxies rewriting responses; ZeroSSL API incidents; misconfigured local reverse proxies on the host; extremely rare in normal operation.","solutions":["Reproduce the raw response: curl -fsSL -X POST https://app.zerossl.com/acme/eab-credentials-email -d 'email=you@example.com' and inspect what actually comes back.","If a MITM proxy is in play, add an exception for app.zerossl.com or configure the host's trust store so the response passes through unmodified.","Retry after a short wait — malformed bodies during ZeroSSL incidents are transient.","Fall back to manual EAB credentials from the ZeroSSL dashboard."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := registerZeroSSL(ctx); err != nil {\n    if strings.Contains(err.Error(), \"decoding API response\") {\n        // malformed payload: usually transient (proxy/CDN glitch); retry with backoff\n        time.Sleep(10 * time.Second)\n        err = registerZeroSSL(ctx)\n    }\n}","preventionTips":["Ensure no MITM proxy rewrites responses from app.zerossl.com.","Use manual EAB credentials in environments with intercepting proxies."],"tags":["tls","acme","zerossl","json","network"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}