cloudflare/pingora · error
body buf exists once a chunk was parsed out of it
Error message
body buf exists once a chunk was parsed out of it
What it means
While finishing a chunked body, the parser detects the terminal 0-size chunk and splits the remaining buffer (trailers/pipelined data) in O(1); it .take()s body_buf and .expect()s it to exist ('body buf exists once a chunk was parsed out of it', body.rs:639). Reaching that branch with no body_buf violates the parser invariant that parsing chunks out of the buffer implies the buffer exists, so this panic indicates an internal bug or desynchronized state, not a caller error.
Source
Thrown at pingora-core/src/protocols/http/v1/body.rs:639
/* expecting_from_io < existing_buf_end */
self.body_state =
self.body_state.multi_chunk(payload_size, expecting_from_io);
return Ok(Some(BufRef::new(0, payload_size)));
}
let (buf_res, last_chunk_size_end) =
self.parse_chunked_buf(existing_buf_start, existing_buf_end)?;
if buf_res.is_some() {
if let Some(idx) = last_chunk_size_end {
// just read the last 0 + CRLF, but not final end CRLF
// Split the rest of the buffer to the start in O(1) so trailers and
// any following pipelined request remain in the same allocation.
// `do_read_chunked_body_final` must not reset this buffer, see the
// `existing_buf_end` handling there.
let mut body_buf = self
.body_buf
.take()
.expect("body buf exists once a chunk was parsed out of it");
trace!(
"last chunk size end buf {:?}",
body_buf[..existing_buf_end].escape_ascii(),
);
body_buf.truncate(existing_buf_end);
self.body_buf = Some(body_buf.split_off(idx));
}
}
Ok(buf_res)
}
}
_ => panic!("wrong body state: {:?}", self.body_state),
}
}
// Returns: BufRef of next body chunk,
// terminating chunk-size index end if read completely (0 + CRLF).
// Note input indices are absolute (to body_buf).View on GitHub (pinned to 0046038bd4)
Solutions
- Upgrade pingora-core to the latest release and retest the offending traffic
- Capture and minimize the failing response (final chunk + trailers) and report it upstream to pingora
- Review any custom body-buffer handling (cache read/write filters) that could take or reset the H1 session buffer mid-parse
Example fix
# before pingora-core = "0.7" # after cargo update -p pingora-core # includes H1 chunked/trailer fixes
Defensive patterns
Strategy: try-catch
Try / catch
// Wrap per-connection proxying so parser panics degrade to 502, not a crash
let outcome = tokio::spawn(handle_connection(stream)).await;
match outcome {
Ok(r) => r,
Err(e) if e.is_panic() => {
log::error!("H1 chunked/trailer parse panicked: {e:?}");
respond_502_and_close()
}
Err(e) => Err(e.into()),
} Prevention
- Exercise trailer and pipelined-after-last-chunk traffic in tests; these are the rare paths here
- Avoid custom body-buffer manipulation (cache readers, filters) that could consume the H1 buffer mid-parse
- Report reproducible cases upstream with the raw response bytes and stay current on pingora-core patches
When it happens
Trigger: A chunked response ending with the final chunk (+ optional trailers) processed through a parser/buffer state where body_buf was already consumed or reset — typically a pingora bug on specific trailer/pipelining sequences, or custom code resetting the session body buffer between reads.
Common situations: Responses with trailers or pipelined follow-up requests after the last chunk; fuzzed chunked streams; mixing cache body readers that consume the buffer with the H1 parser's assumptions.
Related errors
- body buf exists once a partial chunk head was buffered
- must have read body buf
- body buf is initialized before reading trailers
- take_write_lock() called without cache lock
- take_write_lock() called without lock
AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16).
Data as JSON: /api/errors/e0fbd5013257ca54.
Report an issue: GitHub.