ory/hydra · error
Malformed response from the accept endpoint
Error message
Malformed response from the accept endpoint
What it means
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.
Source
Thrown at cmd/cmd_perform_device_flow.go:235
if err != nil {
http.Error(w, fmt.Sprintf("Failed to accept user code request: %s", err), http.StatusInternalServerError)
return
}
defer res.Body.Close() //nolint:errcheck
raw, err := io.ReadAll(io.LimitReader(res.Body, 1<<20))
if err != nil {
http.Error(w, fmt.Sprintf("Failed to read response: %s", err), http.StatusInternalServerError)
return
}
if res.StatusCode != http.StatusOK {
http.Error(w, fmt.Sprintf("Failed to accept user code request: %s", raw), http.StatusInternalServerError)
return
}
var accepted struct {
RedirectTo string `json:"redirect_to"`
}
if err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == "" {
http.Error(w, "Malformed response from the accept endpoint", http.StatusInternalServerError)
return
}
http.Redirect(w, r, accepted.RedirectTo, http.StatusSeeOther)
}
func (s *deviceSrv) GETdone(w http.ResponseWriter, r *http.Request) {
_, _ = fmt.Fprintln(w, "You can now close this window and return to the application.")
}
type userCodeData struct {
UserCode string
DeviceChallenge string
}
var userCodeTemplate = template.Must(template.New("userCode").Parse(`
<html>
<body>View on GitHub (pinned to 4174065ffb)
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.
Example fix
// before
if err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == "" {
http.Error(w, "Malformed response from the accept endpoint", http.StatusInternalServerError)
return
}
// after
if err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == "" {
logger.Errorf("unexpected accept response: %s", raw)
http.Error(w, "Admin endpoint returned an unexpected response — verify server URL", http.StatusBadGateway)
return
} Defensive patterns
Strategy: type-guard
Validate before calling
ct := res.Header.Get("Content-Type")
if !strings.HasPrefix(ct, "application/json") {
return fmt.Errorf("expected JSON from admin endpoint, got %q — check URL/proxy", ct)
} Type guard
func isValidAcceptResponse(raw []byte) bool {
var a struct {
RedirectTo string `json:"redirect_to"`
}
if err := json.Unmarshal(raw, &a); err != nil { return false }
u, err := url.Parse(a.RedirectTo)
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
} Try / catch
var accepted struct {
RedirectTo string `json:"redirect_to"`
}
if err := json.Unmarshal(raw, &accepted); err != nil || accepted.RedirectTo == "" {
log.Printf("unexpected admin payload (content-type=%s): %.512s", res.Header.Get("Content-Type"), raw)
http.Error(w, "malformed admin response", http.StatusBadGateway)
return
} Prevention
- 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)
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- issuer URL must be set unless development mode is enabled
- global secret is not configured
- global secret is too short
- The DSN connection string looks like a SQLite connection, bu
- unsupported DSN type
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/3bbd2897285726ae.
Report an issue: GitHub.