{"record":{"id":"41deb1a813fe7148","repo":"sveltejs/kit","slug":"could-not-deserialize-binary-form-invalid-file-of","errorCode":null,"errorMessage":"Could not deserialize binary form: invalid file offset table","messagePattern":"Could not deserialize binary form: invalid file offset table","errorType":"exception","errorClass":"SvelteKitError","httpStatus":400,"severity":"error","filePath":"packages/kit/src/runtime/form-utils.js","lineNumber":278,"sourceCode":"\tconst data_buffer = await get_buffer(HEADER_BYTES, data_length);\n\tif (!data_buffer) throw deserialize_error('data too short');\n\n\t/** @type {Array<number | undefined>} */\n\tlet file_offsets;\n\t/** @type {number} */\n\tlet files_start_offset;\n\tif (file_offsets_length > 0) {\n\t\t// Read the file offset table\n\t\tconst file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);\n\t\tif (!file_offsets_buffer) throw deserialize_error('file offset table too short');\n\n\t\tconst parsed_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));\n\n\t\tif (\n\t\t\t!Array.isArray(parsed_offsets) ||\n\t\t\tparsed_offsets.some((n) => typeof n !== 'number' || !Number.isInteger(n) || n < 0)\n\t\t) {\n\t\t\tthrow deserialize_error('invalid file offset table');\n\t\t}\n\n\t\tfile_offsets = /** @type {Array<number>} */ (parsed_offsets);\n\t\tfiles_start_offset = HEADER_BYTES + data_length + file_offsets_length;\n\t}\n\n\t/** @type {Array<{ offset: number, size: number }>} */\n\tconst file_spans = [];\n\tconst [data, meta] = devalue.parse(text_decoder.decode(data_buffer), {\n\t\tFile: ([name, type, size, last_modified, index]) => {\n\t\t\tif (\n\t\t\t\ttypeof name !== 'string' ||\n\t\t\t\ttypeof type !== 'string' ||\n\t\t\t\ttypeof size !== 'number' ||\n\t\t\t\ttypeof last_modified !== 'number' ||\n\t\t\t\ttypeof index !== 'number'\n\t\t\t) {\n\t\t\t\tthrow deserialize_error('invalid file metadata');","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/form-utils.js#L260-L296","documentation":"The file offset table read from a binary form payload must be a JSON array of non-negative integers. deserialize_binary_form throws this when the table parses but fails that shape check. This guards against malformed or tampered payloads that would otherwise cause arbitrary file slicing later.","triggerScenarios":"A multipart/form-data action request whose binary payload contains an offset table that is not an array (e.g. an object or string) or contains negative/non-integer/non-number entries — typically from a hand-crafted request, corrupted transfer, or wrong serializer version on the client.","commonSituations":"Proxy or antivirus rewriting the body; client and server on mismatched SvelteKit versions with different binary framing; security scanners fuzzing action endpoints; manual replay of captured requests with edited content.","solutions":["Ensure client and server run the same @sveltejs/kit version so the binary format matches.","Submit the form through SvelteKit's normal flow (native POST or use:enhance) so serialization is canonical.","Check intermediaries (proxies, WAFs, virus scanners) that could rewrite the body.","Log and reject the offending request at the edge if you're seeing deliberate tampering."],"exampleFix":"// before: hand-rolling the payload\nconst body = new Blob([JSON.stringify({ offsets: [-1, 'x'] })]);\n// after: use the library's serializer output unchanged\nawait fetch(actionUrl, { method: 'POST', body: kitSerializedFormData });","handlingStrategy":"validation","validationCode":"const offsets = parsed?.fileOffsets;\nconst valid = Array.isArray(offsets) && offsets.every((n) => typeof n === 'number' && Number.isInteger(n) && n >= 0);","typeGuard":"function isValidOffsetTable(v) {\n  return Array.isArray(v) && v.every((n) => typeof n === 'number' && Number.isInteger(n) && n >= 0);\n}","tryCatchPattern":"try {\n  await deserialize_binary_form(request);\n} catch (e) {\n  if (String(e.message).includes('invalid file offset table')) {\n    return new Response('Malformed request', { status: 400 });\n  }\n  throw e;\n}","preventionTips":["Pin the same @sveltejs/kit version on client and server.","Submit via use:enhance/native POST so payloads are canonical.","Reject malformed bodies at the proxy/WAF before they reach the app."],"tags":["sveltekit","forms","serialization","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}