Detail Bug Report
https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/bugs/bug_b9539ee3-5368-4f10-817b-72cc6a911b05
Introduced in 2c1010e by @shikhar on Sep 5, 2025
Summary
- Context: The service uses a page-based architecture with
PAGE_SIZE = 16 MiB and PageId = u16.
- Bug: Off-by-one error in
MAX_RANGE_END calculation makes the last page (65535) inaccessible.
- Actual vs. expected: Actual: route validation requires
last_byte < MAX_RANGE_END, so any byte at offset 65535 * PAGE_SIZE (start of page 65535) is rejected with HTTP 416. Expected: all pages 0..=65535 should be addressable.
- Impact: Objects larger than ~1.099 TiB cannot serve their last ~16 MiB of data.
Code with Bug
src/service/mod.rs
pub const MAX_RANGE_END: u64 = PAGE_SIZE * PageId::MAX as u64; // <-- BUG 🔴 computes start of last page, not exclusive end
src/service/routes.rs
) if first_byte <= last_byte && last_byte < super::MAX_RANGE_END => { // <-- BUG 🔴 makes bytes at offset == MAX_RANGE_END unreachable
Ok(Self(first_byte..(last_byte + 1)))
}
Explanation
PageId::MAX is 65535, so PAGE_SIZE * PageId::MAX equals the start of page 65535. Because the route layer enforces last_byte < MAX_RANGE_END, the maximum readable byte becomes MAX_RANGE_END - 1, which is the last byte of page 65534—making page 65535 entirely inaccessible.
With PAGE_SIZE = 16,777,216 bytes:
- Current
MAX_RANGE_END = 16,777,216 * 65,535 = 1,099,494,850,560 (start of page 65535)
- Expected exclusive upper bound to allow page 65535:
16,777,216 * 65,536 = 1,099,511,627,776
Codebase Inconsistency
Other parts of the codebase explicitly support PageId values up to 65535, conflicting with the service’s range limit:
src/cache.rs
struct CacheKeyHeader(
/// 16 bits page ID
[u8; 5],
);
src/cache.rs
page_id in 0u16..=u16::MAX
Failing Test
Add to the src/service/mod.rs tests module:
#[test]
fn max_range_end_allows_all_pages() {
let last_page_start = u64::from(PageId::MAX) * PAGE_SIZE;
let last_page_end = last_page_start + PAGE_SIZE;
assert!(
last_page_end <= MAX_RANGE_END,
"Page {} is inaccessible: requires byterange.end = {} but MAX_RANGE_END = {}",
PageId::MAX, last_page_end, MAX_RANGE_END
);
}
Current output:
thread 'service::tests::max_range_end_allows_all_pages' panicked at src/service/mod.rs:642:9:
Page 65535 is inaccessible: requires byterange.end = 1099511627776 but MAX_RANGE_END = 1099494850560
Recommended Fix
src/service/mod.rs
// Before (incorrect)
pub const MAX_RANGE_END: u64 = PAGE_SIZE * PageId::MAX as u64;
// After (correct)
pub const MAX_RANGE_END: u64 = PAGE_SIZE * (PageId::MAX as u64 + 1);
Also update the assertion comment in src/service/mod.rs to match the intended exclusive bound semantics.
History
This bug was introduced in commit 2c1010e (initial commit). Commit d5d5ab7 later fixed an identical off-by-one pattern in translating byte ranges to pages, but did not correct MAX_RANGE_END.
Detail Bug Report
https://app.detail.dev/org_89d327b3-b883-4365-b6a3-46b6701342a9/bugs/bug_b9539ee3-5368-4f10-817b-72cc6a911b05
Introduced in 2c1010e by @shikhar on Sep 5, 2025
Summary
PAGE_SIZE = 16 MiBandPageId = u16.MAX_RANGE_ENDcalculation makes the last page (65535) inaccessible.last_byte < MAX_RANGE_END, so any byte at offset65535 * PAGE_SIZE(start of page 65535) is rejected with HTTP 416. Expected: all pages0..=65535should be addressable.Code with Bug
src/service/mod.rssrc/service/routes.rsExplanation
PageId::MAXis65535, soPAGE_SIZE * PageId::MAXequals the start of page 65535. Because the route layer enforceslast_byte < MAX_RANGE_END, the maximum readable byte becomesMAX_RANGE_END - 1, which is the last byte of page 65534—making page 65535 entirely inaccessible.With
PAGE_SIZE = 16,777,216bytes:MAX_RANGE_END = 16,777,216 * 65,535 = 1,099,494,850,560(start of page 65535)16,777,216 * 65,536 = 1,099,511,627,776Codebase Inconsistency
Other parts of the codebase explicitly support
PageIdvalues up to65535, conflicting with the service’s range limit:src/cache.rssrc/cache.rsFailing Test
Add to the
src/service/mod.rstests module:Current output:
Recommended Fix
src/service/mod.rsAlso update the assertion comment in
src/service/mod.rsto match the intended exclusive bound semantics.History
This bug was introduced in commit
2c1010e(initial commit). Commitd5d5ab7later fixed an identical off-by-one pattern in translating byte ranges to pages, but did not correctMAX_RANGE_END.