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

  1. Upgrade pingora-core to the latest release and retest the offending traffic
  2. Capture and minimize the failing response (final chunk + trailers) and report it upstream to pingora
  3. 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

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


AI-assisted analysis of cloudflare/pingora@0046038bd4 (2026-08-16). Data as JSON: /api/errors/e0fbd5013257ca54. Report an issue: GitHub.