MHSanaei/3x-ui · error · errRemoteResponseTooLarge
%s %s: %w (content-length %d, cap %d)
Error message
%s %s: %w (content-length %d, cap %d)
What it means
Returned by Remote.do when the response's declared Content-Length already exceeds maxRemoteResponseBytes, wrapping errRemoteResponseTooLarge. This is the fast-fail path: it refuses to stream a body the node honestly declared as oversized. It protects the master's memory from a node (or something impersonating one) that returns a gigantic payload.
Source
Thrown at internal/web/runtime/remote.go:273
// Validate status before reading a success payload: a non-OK response's
// body is never used beyond a short diagnostic, so don't let a node force us
// to buffer a large body just to return an HTTP error.
if resp.StatusCode != http.StatusOK {
snippet, _ := io.ReadAll(io.LimitReader(resp.Body, errBodyDiagBytes))
if msg := bytes.TrimSpace(snippet); len(msg) > 0 {
// %q quotes/escapes the untrusted node body so control characters or
// newlines in it can't garble or inject into the error/log output.
return nil, fmt.Errorf("%s %s: HTTP %d: %q", method, path, resp.StatusCode, msg)
}
return nil, fmt.Errorf("%s %s: HTTP %d", method, path, resp.StatusCode)
}
// Fast-fail on an honestly-declared oversize body; the LimitReader below is
// the real guard since Content-Length is untrusted, may be absent, or is -1
// under transparent decompression.
if resp.ContentLength > maxRemoteResponseBytes {
return nil, fmt.Errorf("%s %s: %w (content-length %d, cap %d)", method, path, errRemoteResponseTooLarge, resp.ContentLength, maxRemoteResponseBytes)
}
raw, err := readCappedBody(resp.Body, maxRemoteResponseBytes)
if err != nil {
if errors.Is(err, errRemoteResponseTooLarge) {
return nil, fmt.Errorf("%s %s: %w (cap %d bytes)", method, path, err, maxRemoteResponseBytes)
}
return nil, fmt.Errorf("read body: %w", err)
}
var env envelope
if err := json.Unmarshal(raw, &env); err != nil {
return nil, fmt.Errorf("decode envelope: %w", err)
}
if !env.Success {
return &env, &remoteAPIError{msg: env.Msg}
}
return &env, nilView on GitHub (pinned to ad32144c42)
Solutions
- Check the reported content-length vs cap: if it is a legitimate inbound-list response, shrink the payload (fewer inbounds per node, trim client remarks) or raise maxRemoteResponseBytes in remote.go after measuring real sizes.
- curl -sI the same endpoint on the node to see what the big body actually is — if it is not JSON, the master is hitting the wrong route.
- Verify master and node versions match so list endpoints return the same compact shape.
- Do not wrap or gzip-transform the response in a way that inflates Content-Length (proxy double-encoding).
Example fix
// before: node returns 40MB inbound list // err: GET panel/api/inbounds/list: remote response too large (content-length 41943040, cap 8388608) // after: split clients across more nodes/inbounds, or in remote.go raise the constant after review // const maxRemoteResponseBytes = 64 << 20
Defensive patterns
Strategy: validation
Validate before calling
// Estimate list size before fetching
if nodeInboundCount > safeInboundBudget { // e.g. thousands of clients per node
return errors.New("node payload likely exceeds master cap; split inbounds across nodes")
} Type guard
func isResponseTooLarge(err error) bool {
return err != nil && strings.Contains(err.Error(), "remote response too large")
} Try / catch
if err := remote.ListInboundOptions(ctx); err != nil {
if isResponseTooLarge(err) {
// capacity decision, not a retry: shard or raise cap deliberately
return shardNodeInbounds(nodeID)
}
return err
} Prevention
- Keep per-node inbound/client counts within a planned budget instead of one giant node.
- Measure real list-payload sizes after major client-count growth.
- Never point the master's node address at a non-API URL; a big static file triggers this exact failure.
When it happens
Trigger: An RPC whose response legitimately grew past the cap — e.g. panel/api/inbounds/list on a node with an enormous number of inbounds/clients — or a node endpoint replying with a huge non-JSON payload (log dump, HTML page) because of a version mismatch or wrong route.
Common situations: Node with thousands of inbounds or very large settings JSON; master pointed at a URL that returns something other than the expected API (misconfigured address returning a big static file); a runaway handler on the node serializing internal state.
Related errors
- %s %s: %w (cap %d bytes)
- %s %s: %w
- %s %s: HTTP %d: %q
- %s %s: HTTP %d
- remote inbound with tag %q not found on node %s
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/eeeb76abeb629574.
Report an issue: GitHub.