HelloZeroNet/ZeroNet · error · Exception
No multipart header found
Error message
No multipart header found
What it means
When handling a bigfile upload (actionBigfileUpload), the plugin reads the multipart/form-data stream from WSGI input looking for the b'\r\n' line that terminates the multipart headers. It scans at most 100 lines; if none is found, the request body is not a well-formed multipart upload, so it raises.
Source
Thrown at plugins/Bigfile/BigfilePlugin.py:155
site.content_manager.contents.loadItem(file_info["content_inner_path"]) # reload cache
return {
"merkle_root": merkle_root,
"piece_num": len(piecemap_info["sha512_pieces"]),
"piece_size": piece_size,
"inner_path": inner_path
}
def readMultipartHeaders(self, wsgi_input):
found = False
for i in range(100):
line = wsgi_input.readline()
if line == b"\r\n":
found = True
break
if not found:
raise Exception("No multipart header found")
return i
def actionFile(self, file_path, *args, **kwargs):
if kwargs.get("file_size", 0) > 1024 * 1024 and kwargs.get("path_parts"): # Only check files larger than 1MB
path_parts = kwargs["path_parts"]
site = self.server.site_manager.get(path_parts["address"])
big_file = site.storage.openBigfile(path_parts["inner_path"], prebuffer=2 * 1024 * 1024)
if big_file:
kwargs["file_obj"] = big_file
kwargs["file_size"] = big_file.size
return super(UiRequestPlugin, self).actionFile(file_path, *args, **kwargs)
@PluginManager.registerTo("UiWebsocket")
class UiWebsocketPlugin(object):
def actionBigfileUploadInit(self, to, inner_path, size, protocol="xhr"):
valid_signers = self.site.content_manager.getValidSigners(inner_path)View on GitHub (pinned to 454c0b2e7e)
Solutions
- Ensure the upload request uses multipart/form-data with a correct boundary (let the HTTP client set Content-Type automatically instead of hardcoding it)
- Send the form fields via FormData() rather than a manually serialized body
- Check that the request body is not truncated: verify Content-Length matches the body actually sent
- If sending many/long custom headers, reduce them or increase the 100-line scan limit in readMultipartHeaders
Example fix
// before
fetch(url, { method: 'POST', headers: {'Content-Type': 'multipart/form-data'}, body: JSON.stringify({file: data}) })
// after
const fd = new FormData();
fd.append('file', fileBlob);
fetch(url, { method: 'POST', body: fd }); // browser sets boundary Defensive patterns
Strategy: validation
Validate before calling
// client-side sanity check before upload
if (!(body instanceof FormData)) throw new Error('upload body must be FormData (multipart/form-data)');
const ct = headers.get('Content-Type');
if (ct && !ct.includes('multipart/form-data') && !ct.includes('boundary=')) throw new Error('bad Content-Type: ' + ct); Try / catch
try:
result = site.cmd('bigfileUpload', ...)
except Exception as err:
if 'No multipart header found' in str(err):
fix_request_to_multipart_and_retry()
else:
raise Prevention
- Use FormData / native multipart encoders; never hand-set Content-Type without boundary
- Verify Content-Length matches the serialized body (no truncation)
- Keep custom request headers under the ~100-line header scan limit
- Test uploads through any proxy/middleware to confirm it does not re-encode the body
When it happens
Trigger: POSTing to the bigfile upload action with a body that is not multipart/form-data (e.g. raw JSON or urlencoded), a missing/incorrect Content-Type boundary, a truncated request body, or >100 lines of headers before the blank line.
Common situations: Client (JS fetch/XMLHttpRequest or CLI) forgetting to set the multipart Content-Type with boundary; a proxy or middleware re-encoding the body; uploads where a custom front-end sends extra headers beyond the 100-line scan limit.
Related errors
AI-assisted analysis of HelloZeroNet/ZeroNet@454c0b2e7e (2026-09-02).
Data as JSON: /api/errors/2da373cc9df6399a.
Report an issue: GitHub.