rancher/rancher · warning
cannot read request body: %v
Error message
cannot read request body: %v
What it means
checkCredentials does io.ReadAll(req.Body) and returns HTTP 400 'cannot read request body: %v' when the read itself fails. The handler never got a parsable body: the connection reset mid-upload, the body was truncated by a proxy, or a size limit was enforced upstream.
Source
Thrown at pkg/api/norman/customization/alibaba/handler.go:192
}
writer.Write(serialized)
case "alibabaImageSupportedInstanceTypes":
if serialized, errCode, err = describeImageSupportedInstanceTypes(capabilities, req); err != nil {
logrus.Debugf("[alibaba-handler] error call describeImageSupportedInstanceTypes: %v", err)
util.ReturnHTTPError(writer, req, errCode, err.Error())
return
}
writer.Write(serialized)
default:
handleErr(writer, httperror.NotFound.Status, fmt.Errorf("invalid endpoint %v", resourceType))
}
}
func (h *handler) checkCredentials(req *http.Request) (int, error) {
cred := &Capabilities{}
raw, err := io.ReadAll(req.Body)
if err != nil {
return http.StatusBadRequest, fmt.Errorf("cannot read request body: %v", err)
}
if err = json.Unmarshal(raw, &cred); err != nil {
return http.StatusBadRequest, fmt.Errorf("cannot parse request body: %v", err)
}
if cred.RegionID == "" {
cred.RegionID = defaultRegion
}
if cred.AccessKeyID == "" {
return http.StatusBadRequest, fmt.Errorf("must provide access key ID")
}
if cred.AccessKeySecret == "" {
return http.StatusBadRequest, fmt.Errorf("must provide access key secret")
}
client, err := CreateECSClient(cred.AccessKeyID, cred.AccessKeySecret, cred.RegionID)
if err != nil {View on GitHub (pinned to 932558d4e6)
Solutions
- Retry the request - read failures are usually transient transport errors
- Shrink the payload; only accessKeyId/accessKeySecret/regionId are needed
- Raise proxy body-size and timeout limits on the path to Rancher
- Confirm the client sends Content-Length and completes the body (no dangling chunked stream)
Example fix
// before
await fetch(url, {method: 'POST', body: hugeBlob}); // proxy truncates -> 400
// after
await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({accessKeyId: id, accessKeySecret: secret})
}); Defensive patterns
Strategy: try-catch
Try / catch
try {
const res = await fetch(url, {method: 'POST', body: JSON.stringify(payload)});
if (!res.ok) {
const msg = await res.text();
if (msg.includes('cannot read request body')) {
// transport truncated the upload - safe to retry once
}
}
} catch (e) {
// network-level failure before the server saw a body: retry idempotently
} Prevention
- Keep credential-check bodies tiny - three string fields suffice
- Check proxy body-size limits (nginx client_max_body_size) on API routes
- Retry once on connection reset before reporting an error
When it happens
Trigger: Client aborts or network reset during upload; reverse proxy (nginx client_max_body_size, Traefik limits) truncating; very large or chunked bodies the server rejects; keep-alive recycled mid-request.
Common situations: Flaky client networks; aggressive proxy body-size caps; load balancer idle timeouts on slow uploads.
Related errors
- cannot read request body: %v
- cannot read request body: %v
- use POST for this endpoint
- Invalid password
- invalid username
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/175e5ba444ae8585.
Report an issue: GitHub.