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

  1. Ensure the upload request uses multipart/form-data with a correct boundary (let the HTTP client set Content-Type automatically instead of hardcoding it)
  2. Send the form fields via FormData() rather than a manually serialized body
  3. Check that the request body is not truncated: verify Content-Length matches the body actually sent
  4. 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

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.