From f2d6de9faf70c74550c22d273400a01aef434af5 Mon Sep 17 00:00:00 2001 From: matthiasL-scality Date: Thu, 6 Aug 2026 16:03:51 +0200 Subject: [PATCH 1/2] Fix: handle Scaleway InvalidRequest for large file CopyObject Scaleway returns InvalidRequest (not EntityTooLarge) when CopyObject is called on a file larger than 5 GB. The multipart copy fallback was never triggered for Scaleway builds because the error code check only matched EntityTooLarge. Co-Authored-By: Claude Sonnet 4.6 --- lua/copy_build.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lua/copy_build.lua b/lua/copy_build.lua index 5bafb5a..46a73c6 100644 --- a/lua/copy_build.lua +++ b/lua/copy_build.lua @@ -187,7 +187,8 @@ local current_object = 0 -- larger than the threshold directly to multipart copy. Used in tests to -- exercise the multipart code path without needing actual >5 GB files. -- In production the variable is unset: attempt CopyObject first and only fall --- back to multipart when the backend returns EntityTooLarge. +-- back to multipart when the backend returns EntityTooLarge or InvalidRequest +-- (Scaleway uses InvalidRequest for files larger than 5 GB). -- local copy_size_limit = tonumber(os.getenv("COPY_OBJECT_SIZE_LIMIT")) @@ -258,7 +259,10 @@ else ngx.say("[" .. current_object .. "/" .. total_number_of_objects .. "] " .. object .. " ... ") if object_res.status == 200 then ngx.say('DONE') - elseif object_res.status == 400 and object_res.body:find("EntityTooLarge", 1, true) then + elseif object_res.status == 400 and ( + object_res.body:find("EntityTooLarge", 1, true) or + object_res.body:find("InvalidRequest", 1, true) + ) then ngx.say("large file, switching to multipart copy") ngx.flush(true) local ok, err = multipart_copy(object) From 13976ce0df5a2bbd8f6b4cdd889664b2a23acbe5 Mon Sep 17 00:00:00 2001 From: matthiasL-scality Date: Thu, 6 Aug 2026 16:07:14 +0200 Subject: [PATCH 2/2] Fix: tighten large-file detection to avoid generic InvalidRequest match Use message substring 'copy source is larger' instead of the generic error code InvalidRequest, to avoid triggering multipart fallback for unrelated 400 errors. Update production-mode comment to mention both AWS S3 (EntityTooLarge) and Scaleway error signatures. Co-Authored-By: Claude Sonnet 4.6 --- lua/copy_build.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/copy_build.lua b/lua/copy_build.lua index 46a73c6..b35f51b 100644 --- a/lua/copy_build.lua +++ b/lua/copy_build.lua @@ -240,7 +240,8 @@ if copy_size_limit then else - -- Production mode: CopyObject batch, fall back to multipart on EntityTooLarge. + -- Production mode: CopyObject batch, fall back to multipart on EntityTooLarge + -- (AWS S3) or "copy source is larger" InvalidRequest (Scaleway). for batch_start = 1, total_number_of_objects, batch_size do local batch_end = math.min(batch_start + batch_size - 1, total_number_of_objects) local urls = {} @@ -261,7 +262,7 @@ else ngx.say('DONE') elseif object_res.status == 400 and ( object_res.body:find("EntityTooLarge", 1, true) or - object_res.body:find("InvalidRequest", 1, true) + object_res.body:find("copy source is larger", 1, true) ) then ngx.say("large file, switching to multipart copy") ngx.flush(true)