{"record":{"id":"779890ce35de0c01","repo":"kubernetes/kubernetes","slug":"err-error-779890","errorCode":null,"errorMessage":"err.Error()","messagePattern":"err\\.Error\\(\\)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"staging/src/k8s.io/pod-security-admission/cmd/webhook/server/server.go","lineNumber":317,"sourceCode":"\t}\n\n\tif err := s.delegate.CompleteConfiguration(); err != nil {\n\t\treturn nil, fmt.Errorf(\"configuration error: %w\", err)\n\t}\n\tif err := s.delegate.ValidateConfiguration(); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid configuration: %w\", err)\n\t}\n\n\treturn s, nil\n}\n\nfunc writeResponse(w http.ResponseWriter, review *admissionv1.AdmissionReview) {\n\t// Webhooks should always respond with a 200 HTTP status code when an AdmissionResponse can be sent.\n\t// In an error case, the true status code is captured in the response.result.code\n\tif err := json.NewEncoder(w).Encode(review); err != nil {\n\t\tklog.ErrorS(err, \"Failed to encode response\")\n\t\t// Unable to send an AdmissionResponse, fall back to an HTTP error.\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t}\n}\n\n// parseTimeout parses the given HTTP request URL and extracts the timeout query parameter\n// value if specified by the user.\n// If a timeout is not specified the function returns false and err is set to nil\n// If the value specified is malformed then the function returns false and err is set\nfunc parseTimeout(req *http.Request) (time.Duration, bool, error) {\n\tvalue := req.URL.Query().Get(\"timeout\")\n\tif value == \"\" {\n\t\treturn 0, false, nil\n\t}\n\n\ttimeout, err := time.ParseDuration(value)\n\tif err != nil {\n\t\treturn 0, false, fmt.Errorf(\"invalid timeout query: %w\", err)\n\t}\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/b882c60b4023bdf09264c2d5d30a2cadebc240fb/staging/src/k8s.io/pod-security-admission/cmd/webhook/server/server.go#L299-L335","documentation":"500 Internal Server Error at server.go:317, the fallback inside writeResponse when json.NewEncoder(w).Encode(review) fails (the encode error is logged at server.go:315 and then its .Error() string is sent to the client). Encoding fails when the AdmissionResponse cannot be JSON-serialized — typically because a nested Status or Warning carries a non-marshalable field, or the response was already partially written and the connection broke.","triggerScenarios":"json.Encode returns an error mid-write (connection closed by client, response already started); a response field of an unsupported Go type slipped into the AdmissionReview; extremely large response objects; a Status with custom fields not understood by the encoder.","commonSituations":"Client (apiserver) cancelling the webhook call right after the response starts streaming; a custom evaluator that injects non-serializable data; webhook behind a proxy with a short response timeout; concurrent close during graceful shutdown.","solutions":["Check the webhook logs for the 'Failed to encode response' line — it carries the underlying encode error.","Verify the AdmissionResponse returned by the delegate is a plain admissionv1.AdmissionResponse without custom/non-serializable fields.","Ensure the apiserver's webhook timeout (timeoutSeconds) is not shorter than the time the webhook needs to respond.","If the client is closing early, investigate apiserver-side cancellation (context deadline, request aborted).","Buffer the response before writing (encode to a bytes.Buffer first, then w.Write) so a mid-encode failure does not leave a half-written body — though the upstream code encodes directly to w."],"exampleFix":"// before: encode straight to the ResponseWriter; a mid-encode error\n// leaves a half-written body and only then calls http.Error\nfunc writeResponse(w http.ResponseWriter, review *admissionv1.AdmissionReview) {\n    if err := json.NewEncoder(w).Encode(review); err != nil {\n        http.Error(w, err.Error(), http.StatusInternalServerError)\n    }\n}\n\n// after: buffer so encode failures surface before any bytes are sent\nfunc writeResponse(w http.ResponseWriter, review *admissionv1.AdmissionReview) {\n    buf := &bytes.Buffer{}\n    if err := json.NewEncoder(buf).Encode(review); err != nil {\n        klog.ErrorS(err, \"Failed to encode response\")\n        http.Error(w, err.Error(), http.StatusInternalServerError)\n        return\n    }\n    w.Header().Set(\"Content-Type\", \"application/json\")\n    w.Write(buf.Bytes())\n}","handlingStrategy":"try-catch","validationCode":"// Server-side hardening: encode into a buffer first so an encode failure\n// never leaves a half-written response.\nfunc safeWriteResponse(w http.ResponseWriter, review *admissionv1.AdmissionReview) error {\n    buf := &bytes.Buffer{}\n    if err := json.NewEncoder(buf).Encode(review); err != nil {\n        return err\n    }\n    w.Header().Set(\"Content-Type\", \"application/json\")\n    _, err := w.Write(buf.Bytes())\n    return err\n}","typeGuard":"// Ensure the response is JSON-serializable before touching the wire.\nfunc isSerializable(review *admissionv1.AdmissionReview) error {\n    if _, err := json.Marshal(review); err != nil {\n        return fmt.Errorf(\"response not serializable: %w\", err)\n    }\n    return nil\n}","tryCatchPattern":"// Server: log encode errors and fall back cleanly; never panic.\nif err := safeWriteResponse(w, review); err != nil {\n    klog.ErrorS(err, \"Failed to encode response\")\n    if !headersWritten(w) {\n        http.Error(w, err.Error(), http.StatusInternalServerError)\n    }\n}","preventionTips":["Buffer-encode before writing to avoid half-written bodies.","Do not inject custom/non-serializable fields into AdmissionResponse.","Size the apiserver webhook timeout generously.","Watch the 'Failed to encode response' log line as an SLO signal."],"tags":["webhook","pod-security-admission","encoding","response","go"],"analyzedSha":"b882c60b4023bdf09264c2d5d30a2cadebc240fb","analyzedAt":"2026-08-07T04:07:48.144Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}