From 8cd8b5cf0f02ed9a22af8430617eb5ee938e91f9 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 6 Aug 2026 20:50:18 -0300 Subject: [PATCH] Fix 416 error on files whose size is an exact multiple of 10 MiB The multipart download loop runs floor(size/chunk)+1 times. For any size that is not an exact multiple of the chunk size that equals ceil(size/chunk), so the extra trip is harmless and the bug is invisible. When the size *is* an exact multiple it is one trip too many, and that trip requests "bytes=-" - a range starting at EOF, which the Graph API answers with HTTP 416. GetItemContentStream returns that as a fatal error, so the file can never be read: every open() fails with EREMOTEIO for as long as the content is not cached, and clearing the cache only forces the failing path again. Observed on a 146800640 byte file, exactly 14 chunks: all 14 ranges download, then a 15th is requested and fails. In a tree of ~88600 files, every file whose size was an exact multiple of 10485760 was unreadable, and no other file was affected. --- fs/graph/drive_item.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/graph/drive_item.go b/fs/graph/drive_item.go index 4b69ad72..45b81ad5 100644 --- a/fs/graph/drive_item.go +++ b/fs/graph/drive_item.go @@ -147,7 +147,11 @@ func GetItemContentStream(id string, auth *Auth, output io.Writer) (uint64, erro // multipart download var n uint64 - for i := 0; i < int(item.Size/downloadChunkSize)+1; i++ { + // The trip count must be ceil(size/chunk). floor(size/chunk)+1 agrees with + // that for every size except an exact multiple of the chunk size, where it is + // one too many and the final request asks for a range starting at EOF - which + // the API answers with 416, making the item permanently unreadable. + for i := 0; i < int((item.Size+downloadChunkSize-1)/downloadChunkSize); i++ { start := i * downloadChunkSize end := start + downloadChunkSize - 1 log.Info().