sveltejs/kit · error · SvelteKitError

Could not deserialize binary form: duplicate file offset…

Error message

Could not deserialize binary form: duplicate file offset table index

What it means

Each entry in the binary form's file offset table must be used by exactly one file's metadata 'index'. deserialize_binary_form marks each offset as used (sets it to undefined); if a second file references the same index, or an index is out of range, it throws this error to block duplicated or aliased file references.

Solutions

  1. Submit forms through SvelteKit's standard flow so indexes are generated correctly.
  2. Match client/server @sveltejs/kit versions.
  3. Reject malformed requests at proxy/WAF level if you're under attack.
  4. Clear caches/redeploy if a stale mismatched client bundle is in circulation.

Example fix

// before: reusing an index in custom serialization
meta.files = [{ name: 'a', index: 0 }, { name: 'b', index: 0 }];
// after: unique index per file
meta.files = [{ name: 'a', index: 0 }, { name: 'b', index: 1 }];
Defensive patterns

Strategy: validation

Validate before calling

const seen = new Set();
for (const f of meta.files) {
  if (seen.has(f.index)) throw new Error('duplicate file index ' + f.index);
  seen.add(f.index);
}

Type guard

function hasUniqueIndexes(files) {
  const seen = new Set();
  return files.every((f) => !seen.has(f.index) && seen.add(f.index) !== undefined);
}

Try / catch

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

Prevention

When it happens

Trigger: A multipart/form-data action request where two file entries share the same offset-table index, or where an index is >= the table length — from corrupted payloads, hand-crafted requests, or serializer/format mismatches.

Common situations: Fuzzing or deliberate tampering with action endpoints; middleware that rewrites the JSON section; version-skewed client/server binaries producing inconsistent index tables.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

	const file_spans = [];
	const [data, meta] = devalue.parse(text_decoder.decode(data_buffer), {
		File: ([name, type, size, last_modified, index]) => {
			if (
				typeof name !== 'string' ||
				typeof type !== 'string' ||
				typeof size !== 'number' ||
				typeof last_modified !== 'number' ||
				typeof index !== 'number'
			) {
				throw deserialize_error('invalid file metadata');
			}

			let offset = file_offsets[index];

			// Check that the file offset table entry has not been already
			// used. If not, immediately mark it as used.
			if (offset === undefined) {
				throw deserialize_error('duplicate file offset table index');
			}
			file_offsets[index] = undefined;

			offset += files_start_offset;

			file_spans.push({ offset, size });

			return new Proxy(new LazyFile(name, type, size, last_modified, get_chunk, offset), {
				getPrototypeOf() {
					// Trick validators into thinking this is a normal File
					return File.prototype;
				}
			});
		}
	});

	// Sort file spans in increasing order primarily by offset
	// and secondarily by size (to allow 0-length files).

View on GitHub (pinned to 03f1687fe6)