Skip to content

ct/l0: preserve the produce-time record crc on the read path - #31375

Merged
andrwng merged 1 commit into
redpanda-data:devfrom
andrwng:placeholder-crc
Jul 31, 2026
Merged

ct/l0: preserve the produce-time record crc on the read path#31375
andrwng merged 1 commit into
redpanda-data:devfrom
andrwng:placeholder-crc

Conversation

@andrwng

@andrwng andrwng commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Previously, when L0 materialized record batches from the payloads in object storage, we were resetting the record-batch crc and rederiving it from the materialized payload data, rather than using the crc in object storage that were written at produce time. This meant that we wouldn't have detected a corrupted bit at rest when served from object storage.

Updates the record-batch materialization code to use the record-batch crc and only recompute the header_crc (needed since neither the placeholder nor the object storage batch have the full materialized-batch header_crc with correct offset and size).

Backports Required

  • none - not a bug fix
  • none - this is a backport
  • none - issue does not exist in previous branches
  • none - papercut/not impactful enough to backport
  • v26.2.x
  • v26.1.x
  • v25.3.x

Release Notes

Bug Fixes

  • Fixes a bug where corrupted storage would not yield a bad CRC in returned record batches.

Previously, when L0 materialized record batches from the payloads in
object storage, we were resetting the record-batch crc and rederiving
it from the materialized payload data, rather than using the crc in
object storage that were written at produce time. This meant that we
wouldn't have detected a corrupted bit at rest when served from object
storage.

Updates the record-batch materialization code to use the record-batch
crc and only recompute the header_crc (needed since neither the
placeholder nor the object storage batch have the full
materialized-batch header_crc with correct offset and size).
Copilot AI review requested due to automatic review settings July 31, 2026 05:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes L0 record-batch materialization to preserve the produce-time record CRC from object storage (so corruption-at-rest remains detectable), while still recomputing the internal header CRC where needed for the materialized header.

Changes:

  • Preserve produce-time record_batch_header.crc during placeholder/header merging rather than recomputing it over materialized bytes.
  • Recompute size_bytes and header_crc for the merged/materialized header to reflect updated offsets/sizes.
  • Add an end-to-end regression test that flips a bit in an uploaded L0 object and asserts the client rejects it.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/v/cloud_topics/tests/end_to_end_test.cc Adds regression coverage for detecting corrupted L0 object data via client CRC checks.
src/v/cloud_topics/tests/BUILD Adds the chunked_vector dependency needed by the new test harness usage.
src/v/cloud_topics/level_zero/stm/placeholder.cc Preserves produce-time batch CRC while recomputing size/header CRC for the merged header.
src/v/cloud_topics/level_zero/reader/materialized_extent.cc Stops recomputing produce-time CRC during raft-data batch materialization (but needs to keep header CRC consistent after mutating the header).

Comment on lines +104 to 106
// base_offset comes from the placeholder; the serialized batch has none.
header.base_offset = kafka::offset_cast(ext.meta.base_offset);
header.crc = model::crc_record_batch(header, records_bytes);
crc::crc32c crc;
model::crc_record_batch_header(crc, header);
header.header_crc = crc.value();
model::record_batch batch(
}
}

// Regression test for an incorrect integity check: previous versions of
@andrwng
andrwng requested review from Lazin, WillemKauf and dotnwat July 31, 2026 16:45
@andrwng
andrwng merged commit 4bc6529 into redpanda-data:dev Jul 31, 2026
18 checks passed
@vbotbuildovich

Copy link
Copy Markdown
Collaborator

/backport v26.2.x

@vbotbuildovich

Copy link
Copy Markdown
Collaborator

/backport v26.1.x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants