{"record":{"id":"3bbd2897285726ae","repo":"ory/hydra","slug":"malformed-response-from-the-accept-endpoint","errorCode":null,"errorMessage":"Malformed response from the accept endpoint","messagePattern":"Malformed response from the accept endpoint","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"cmd/cmd_perform_device_flow.go","lineNumber":235,"sourceCode":"\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to accept user code request: %s\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tdefer res.Body.Close() //nolint:errcheck\n\traw, err := io.ReadAll(io.LimitReader(res.Body, 1<<20))\n\tif err != nil {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to read response: %s\", err), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tif res.StatusCode != http.StatusOK {\n\t\thttp.Error(w, fmt.Sprintf(\"Failed to accept user code request: %s\", raw), http.StatusInternalServerError)\n\t\treturn\n\t}\n\tvar accepted struct {\n\t\tRedirectTo string `json:\"redirect_to\"`\n\t}\n\tif err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == \"\" {\n\t\thttp.Error(w, \"Malformed response from the accept endpoint\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\thttp.Redirect(w, r, accepted.RedirectTo, http.StatusSeeOther)\n}\n\nfunc (s *deviceSrv) GETdone(w http.ResponseWriter, r *http.Request) {\n\t_, _ = fmt.Fprintln(w, \"You can now close this window and return to the application.\")\n}\n\ntype userCodeData struct {\n\tUserCode        string\n\tDeviceChallenge string\n}\n\nvar userCodeTemplate = template.Must(template.New(\"userCode\").Parse(`\n<html>\n<body>","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/ory/hydra/blob/4174065ffb052799890f7480f5360a877a67ffc1/cmd/cmd_perform_device_flow.go#L217-L253","documentation":"Returned when the admin device-accept response either is not valid JSON or lacks the required redirect_to field (json.Unmarshal error or empty accepted.RedirectTo). Hydra's admin API contract says a successful accept returns {\"redirect_to\": \"...\"}; anything else is treated as a contract violation and the handler returns a 500 with this fixed message.","triggerScenarios":"json.Unmarshal(raw, &accepted) fails, or unmarshal succeeds but accepted.RedirectTo == \"\" — the endpoint returned an unexpected payload (empty body, HTML error page from a proxy, or a Hydra version whose accept response shape differs).","commonSituations":"Pointing cfg.Servers[0].URL at a non-Hydra service or through a proxy that returns an HTML 200 page; running against an older/newer Ory Hydra with a changed admin response schema; content-type negotiation confusion returning a different encoding.","solutions":["curl the accept endpoint and confirm the 200 body is JSON containing redirect_to; if it's HTML, fix the URL/proxy so it hits Hydra admin directly.","Check the Hydra version's API docs for the device-accept response schema and pin a compatible version.","Log the raw body before unmarshaling so the unexpected payload is visible in server logs."],"exampleFix":"// before\nif err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == \"\" {\n\thttp.Error(w, \"Malformed response from the accept endpoint\", http.StatusInternalServerError)\n\treturn\n}\n// after\nif err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == \"\" {\n\tlogger.Errorf(\"unexpected accept response: %s\", raw)\n\thttp.Error(w, \"Admin endpoint returned an unexpected response — verify server URL\", http.StatusBadGateway)\n\treturn\n}","handlingStrategy":"type-guard","validationCode":"ct := res.Header.Get(\"Content-Type\")\nif !strings.HasPrefix(ct, \"application/json\") {\n\treturn fmt.Errorf(\"expected JSON from admin endpoint, got %q — check URL/proxy\", ct)\n}","typeGuard":"func isValidAcceptResponse(raw []byte) bool {\n\tvar a struct {\n\t\tRedirectTo string `json:\"redirect_to\"`\n\t}\n\tif err := json.Unmarshal(raw, &a); err != nil { return false }\n\tu, err := url.Parse(a.RedirectTo)\n\treturn err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\")\n}","tryCatchPattern":"var accepted struct {\n\tRedirectTo string `json:\"redirect_to\"`\n}\nif err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == \"\" {\n\tlog.Printf(\"unexpected admin payload (content-type=%s): %.512s\", res.Header.Get(\"Content-Type\"), raw)\n\thttp.Error(w, \"malformed admin response\", http.StatusBadGateway)\n\treturn\n}","preventionTips":["Log the raw response body before unmarshaling so schema surprises are debuggable","Pin a Hydra version and verify the accept response contract after upgrades","Ensure no proxy intercepts and rewrites admin responses (HTML error pages arrive as 200)"],"tags":["json","hydra","api-contract"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"4174065ffb052799890f7480f5360a877a67ffc1","analyzedAt":"2026-09-03T14:52:41.581Z","contentChangedAt":"2026-09-03T14:52:41.581Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}