sveltejs/kit · error · SvelteKitError
Could not deserialize binary form: file offset table too sho
Error message
Could not deserialize binary form: file offset table too short
What it means
SvelteKit's binary form serialization encodes uploaded files in one blob after a JSON payload, with a separate file offset table describing where each file's bytes start. deserialize_binary_form reads that offset table from the request body; if the remaining bytes are shorter than the table's declared length, it throws this error. It means the incoming request body is truncated, corrupted, or was not produced by SvelteKit's serialize_binary_form.
Source
Thrown at packages/kit/src/runtime/form-utils.js:270
const data_length = header_view.getUint32(1, true);
const file_offsets_length = header_view.getUint16(5, true);
// Validation uses embedded binary header fields (data_length, file_offsets_length)
// rather than Content-Length, which proxies/middleboxes may strip or corrupt.
// See: https://github.com/sveltejs/kit/issues/15299
// Read the form data
const data_buffer = await get_buffer(HEADER_BYTES, data_length);
if (!data_buffer) throw deserialize_error('data too short');
/** @type {Array<number | undefined>} */
let file_offsets;
/** @type {number} */
let files_start_offset;
if (file_offsets_length > 0) {
// Read the file offset table
const file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);
if (!file_offsets_buffer) throw deserialize_error('file offset table too short');
const parsed_offsets = JSON.parse(text_decoder.decode(file_offsets_buffer));
if (
!Array.isArray(parsed_offsets) ||
parsed_offsets.some((n) => typeof n !== 'number' || !Number.isInteger(n) || n < 0)
) {
throw deserialize_error('invalid file offset table');
}
file_offsets = /** @type {Array<number>} */ (parsed_offsets);
files_start_offset = HEADER_BYTES + data_length + file_offsets_length;
}
/** @type {Array<{ offset: number, size: number }>} */
const file_spans = [];
const [data, meta] = devalue.parse(text_decoder.decode(data_buffer), {
File: ([name, type, size, last_modified, index]) => {View on GitHub (pinned to 03f1687fe6)
Solutions
- Verify the upload reaches the server intact: check Content-Length vs received bytes and any proxy body-size/timeout limits.
- Ensure the request is POSTed by SvelteKit's own form submission code (use: enhance, native form POST) rather than hand-built fetch calls.
- Remove middleware that consumes or rewrites the request body before SvelteKit deserializes it.
- Retry the upload; if reproducible, log the payload length and header bytes to confirm corruption source.
Example fix
// before: custom fetch that strips body framing
fetch(actionUrl, { method: 'POST', body: JSON.stringify({ data }) });
// after: let SvelteKit serialize the form
import { enhance } from '$app/forms';
<form method="POST" use:enhance> Defensive patterns
Strategy: validation
Validate before calling
// client side, before sending
const body = await request.clone().arrayBuffer();
if (body.byteLength < expectedHeaderBytes) throw new Error('truncated form payload'); Try / catch
try {
await deserialize_binary_form(request);
} catch (e) {
if (String(e.message).includes('file offset table too short')) {
return new Response('Corrupted upload, please retry', { status: 400 });
}
throw e;
} Prevention
- Use SvelteKit's use:enhance or native form POST, never hand-built fetch bodies.
- Check proxy/CDN body size and timeout limits for large uploads.
- Don't add middleware that consumes the request stream before the framework.
- Monitor Content-Length vs received bytes server-side to detect truncation.
When it happens
Trigger: A POST to a SvelteKit action with enctype multipart/form-data whose body was truncated (proxy/CDN cut it off, client aborted mid-upload), a manually crafted or tampered binary payload with a wrong file-offset-table length in the header, or replaying an old/partial body.
Common situations: Reverse proxies or load balancers with short body timeouts dropping large uploads; fetch wrappers that re-serialize the request and mangle the binary framing; malware/scanner tampering; custom middleware consuming part of the request stream before SvelteKit reads it.
Related errors
- Could not deserialize binary form: invalid file offset table
- Could not deserialize binary form: invalid file metadata
- Could not deserialize binary form: duplicate file offset tab
- Could not deserialize binary form: gaps in file data
- Could not deserialize binary form: overlapping file data
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/6a59a09b156700b4.
Report an issue: GitHub.