ory/kratos · error
webhook response body could not be read
Error message
webhook response body could not be read
What it means
The webhook returned HTTP 200 and the courier tried to read its body through the pre-limited reader, but io.ReadAll failed. This is an I/O-level failure while streaming the response (connection reset mid-body, read timeout), not a content problem.
Solutions
- Retry the flow - transient network truncation is the most common cause
- Check for proxies or load balancers that cut long-lived response bodies
- Verify the webhook endpoint closes responses cleanly
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at selfservice/hook/web_hook.go:468 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/c92a9771b6974563.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/hook/web_hook.go:468
}
}
return res
}
func parseWebhookResponse(resp *http.Response, id *identity.Identity) (err error) {
if resp == nil {
return errors.Errorf("empty response provided from the webhook")
}
if resp.StatusCode == http.StatusOK {
type localIdentity identity.Identity
var hookResponse struct {
Identity *localIdentity `json:"identity"`
}
// io.ReadAll is safe, because resp.Body is already a limited reader.
body, err := io.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "webhook response body could not be read")
}
if err = json.Unmarshal(body, &hookResponse); err != nil {
return errors.Wrap(err, "webhook response could not be unmarshalled properly from JSON")
}
if hookResponse.Identity == nil {
return nil
}
if len(hookResponse.Identity.Traits) > 0 {
id.Traits = hookResponse.Identity.Traits
}
if len(hookResponse.Identity.SchemaID) > 0 {
id.SchemaID = hookResponse.Identity.SchemaID
}
if len(hookResponse.Identity.State) > 0 {View on GitHub (pinned to b86338da04)