sveltejs/kit · error · SvelteKitError

Could not deserialize binary form: overlapping file data

Error message

Could not deserialize binary form: overlapping file data

What it means

Companion check to 'gaps in file data': if one file's declared region extends past the next file's start offset, the regions overlap and the payload is inconsistent. deserialize_binary_form throws this to prevent corrupted or maliciously overlapping byte ranges from being extracted as files.

Source

Thrown at packages/kit/src/runtime/form-utils.js:335

			});
		}
	});

	// Sort file spans in increasing order primarily by offset
	// and secondarily by size (to allow 0-length files).
	file_spans.sort((a, b) => a.offset - b.offset || a.size - b.size);

	// Check that file spans do not overlap and there are no gaps between them.
	for (let i = 1; i < file_spans.length; i++) {
		const previous = file_spans[i - 1];
		const current = file_spans[i];

		const previous_end = previous.offset + previous.size;
		if (previous_end < current.offset) {
			throw deserialize_error('gaps in file data');
		}
		if (previous_end > current.offset) {
			throw deserialize_error('overlapping file data');
		}
	}

	// Read the request body asynchronously so it doesn't stall
	void (async () => {
		let has_more = true;
		while (has_more) {
			const chunk = await get_chunk(chunks.length);
			has_more = !!chunk;
		}
	})().catch(noop); // prevent unhandled rejection potentially crashing the process

	return { data, meta, form_data: null };
}
/**
 * @param {string} message
 */
function deserialize_error(message) {

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Keep @sveltejs/kit versions identical on client and server.
  2. Only submit via SvelteKit's canonical serialization path.
  3. Reject malformed requests at the edge; log source IPs if it looks like probing.
  4. Confirm no middleware mutates the JSON metadata of the request body.

Example fix

// before: overlapping spans
offsets: [0, 30], sizes: [50, 20] // file 1 ends at 50 > next start 30
// after: non-overlapping spans
offsets: [0, 50], sizes: [50, 20]
Defensive patterns

Strategy: validation

Validate before calling

spans.sort((a, b) => a.offset - b.offset);
for (let i = 1; i < spans.length; i++) {
  if (spans[i - 1].offset + spans[i - 1].size > spans[i].offset) throw new Error('overlapping spans');
}

Try / catch

try {
  await deserialize_binary_form(request);
} catch (e) {
  if (String(e.message).includes('overlapping file data')) {
    return new Response('Malformed request', { status: 400 });
  }
  throw e;
}

Prevention

When it happens

Trigger: A multipart/form-data action request whose offset table and file sizes define overlapping byte ranges — from tampered payloads, hand-crafted requests, or mismatched serializer versions.

Common situations: Attackers probing action endpoints with crafted offsets; middleware rewriting payload sections; version skew between client and server binary formats.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/53fbc81f816b360c. Report an issue: GitHub.