JuliusBrussee/caveman · error · ErrBodyTooLarge

: bytes (limit )

Error message

%w: %d bytes (limit %d)

What it means

Payload refuses bodies larger than MaxPayloadBytes before doing any redaction work. The error wraps ErrBodyTooLarge so callers can detect oversize input with errors.Is, and reports the actual byte count and the configured limit so the caller knows how far over the ceiling the body is.

Solutions

  1. Check len(body) against redact.MaxPayloadBytes before calling Payload and truncate or reject upstream.
  2. Detect the sentinel with errors.Is(err, redact.ErrBodyTooLarge) and surface a clear 'body too large' outcome to your caller.
  3. If larger bodies are legitimate, adjust the capture ceiling in your pipeline before invoking Payload rather than expecting Payload to accept them.

Example fix

// before
out, report, err := redact.Payload(rawBody, rules)
// after
if len(rawBody) > redact.MaxPayloadBytes {
    rawBody = rawBody[:redact.MaxPayloadBytes]
}
out, report, err := redact.Payload(rawBody, rules)
Defensive patterns

Strategy: validation

Validate before calling

if len(body) > redact.MaxPayloadBytes {
    return fmt.Errorf("refusing to redact: body is %d bytes, limit is %d", len(body), redact.MaxPayloadBytes)
}

Try / catch

out, report, err := redact.Payload(body, rules)
if errors.Is(err, redact.ErrBodyTooLarge) {
    // handle oversize body: truncate, drop, or flag
}

Prevention

When it happens

Trigger: Calling shared/platform/redact.Payload with a body whose len(body) exceeds MaxPayloadBytes (the capture ceiling). E.g. passing a multi-MiB request body, or a large adversarial fixture, or any input where the caller skipped its own size pre-check.

Common situations: Proxying/logging large uploads without truncating first; a limit lowered via default configuration while traffic still contains big payloads; tests/benchmarks feeding 4MiB+ bodies to probe ceiling behavior.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/f12bb1f739aa63a1. Report an issue: GitHub.

Appendix: source

Thrown at shared/platform/redact/payload.go:476

//
// rules are the organization's enabled redaction_rules rows. They are additive
// only — the built-in floor runs first and cannot be disabled, shadowed, or
// reordered by anything a tenant configures.
//
// The returned slice ALIASES body when no rule fired; body is never mutated
// (TestPayloadDoesNotMutateInput), so this is safe to read, but a caller that
// intends to mutate the result in place must copy it first.
//
// Payload does not judge how BROAD a rule is. A pattern like ".+" compiles,
// matches, and collapses the whole body into one placeholder — a self-inflicted
// loss of corpus value, not a leak, and the only pattern shapes rejected here
// are the ones that are unusable rather than merely greedy. Rejecting breadth
// belongs at rule-write time, where an operator is present to see the error;
// there is no such surface yet (see the H1 report's concern on the missing
// redaction_rules validator).
func Payload(body []byte, rules []Rule) ([]byte, RedactionReport, error) {
	if len(body) > MaxPayloadBytes {
		return nil, RedactionReport{}, fmt.Errorf("%w: %d bytes (limit %d)", ErrBodyTooLarge, len(body), MaxPayloadBytes)
	}
	orgRules, fingerprint, err := compileOrgRules(rules)
	if err != nil {
		return nil, RedactionReport{}, err
	}

	sum := sha256.Sum256([]byte(builtinRuleSetFingerprint + "\x00" + fingerprint))
	report := RedactionReport{
		RuleSetHash: hex.EncodeToString(sum[:16]),
		BytesIn:     len(body),
	}

	out := body
	// The prescreen is derived ONCE, then re-derived only after a rule whose
	// replacement can introduce a needle (see replIntroducesNeedle). Of the
	// built-ins only three can, and only when they actually fire.
	lowered := asciiLower(out)
	// Built-ins first: whatever an org rule does afterwards, it acts on a body

View on GitHub (pinned to 3ee70a1026)