{"record":{"id":"2da373cc9df6399a","repo":"HelloZeroNet/ZeroNet","slug":"no-multipart-header-found","errorCode":null,"errorMessage":"No multipart header found","messagePattern":"No multipart header found","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"plugins/Bigfile/BigfilePlugin.py","lineNumber":155,"sourceCode":"\n            site.content_manager.contents.loadItem(file_info[\"content_inner_path\"])  # reload cache\n\n        return {\n            \"merkle_root\": merkle_root,\n            \"piece_num\": len(piecemap_info[\"sha512_pieces\"]),\n            \"piece_size\": piece_size,\n            \"inner_path\": inner_path\n        }\n\n    def readMultipartHeaders(self, wsgi_input):\n        found = False\n        for i in range(100):\n            line = wsgi_input.readline()\n            if line == b\"\\r\\n\":\n                found = True\n                break\n        if not found:\n            raise Exception(\"No multipart header found\")\n        return i\n\n    def actionFile(self, file_path, *args, **kwargs):\n        if kwargs.get(\"file_size\", 0) > 1024 * 1024 and kwargs.get(\"path_parts\"):  # Only check files larger than 1MB\n            path_parts = kwargs[\"path_parts\"]\n            site = self.server.site_manager.get(path_parts[\"address\"])\n            big_file = site.storage.openBigfile(path_parts[\"inner_path\"], prebuffer=2 * 1024 * 1024)\n            if big_file:\n                kwargs[\"file_obj\"] = big_file\n                kwargs[\"file_size\"] = big_file.size\n\n        return super(UiRequestPlugin, self).actionFile(file_path, *args, **kwargs)\n\n\n@PluginManager.registerTo(\"UiWebsocket\")\nclass UiWebsocketPlugin(object):\n    def actionBigfileUploadInit(self, to, inner_path, size, protocol=\"xhr\"):\n        valid_signers = self.site.content_manager.getValidSigners(inner_path)","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/HelloZeroNet/ZeroNet/blob/454c0b2e7e000fda7000cba49027541fbf327b96/plugins/Bigfile/BigfilePlugin.py#L137-L173","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nfetch(url, { method: 'POST', headers: {'Content-Type': 'multipart/form-data'}, body: JSON.stringify({file: data}) })\n// after\nconst fd = new FormData();\nfd.append('file', fileBlob);\nfetch(url, { method: 'POST', body: fd }); // browser sets boundary","handlingStrategy":"validation","validationCode":"// client-side sanity check before upload\nif (!(body instanceof FormData)) throw new Error('upload body must be FormData (multipart/form-data)');\nconst ct = headers.get('Content-Type');\nif (ct && !ct.includes('multipart/form-data') && !ct.includes('boundary=')) throw new Error('bad Content-Type: ' + ct);","typeGuard":null,"tryCatchPattern":"try:\n    result = site.cmd('bigfileUpload', ...)\nexcept Exception as err:\n    if 'No multipart header found' in str(err):\n        fix_request_to_multipart_and_retry()\n    else:\n        raise","preventionTips":["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"],"tags":["http","multipart","upload","request-format"],"backgroundTag":"malformed-multipart-body","analyzedSha":"454c0b2e7e000fda7000cba49027541fbf327b96","analyzedAt":"2026-09-02T19:46:57.278Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}