{"record":{"id":"2a381d7a964bf60c","repo":"transloadit/uppy","slug":"uploaded-only-bytesuploaded-of-this-size-wit","errorCode":null,"errorMessage":"uploaded only ${bytesUploaded} of ${this.size} with status: ${response.statusCode}","messagePattern":"uploaded only (.+?) of (.+?) with status: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/companion/src/server/Uploader.ts","lineNumber":845,"sourceCode":"    } else {\n      if (this.size != null) {\n        reqOptions.headers = {\n          ...reqOptions.headers,\n          'content-length': `${this.size}`,\n        }\n      }\n      reqOptions.body = stream\n    }\n\n    try {\n      const httpMethod =\n        (this.options.httpMethod ?? '').toUpperCase() === 'PUT' ? 'put' : 'post'\n      const response = await got[httpMethod](url, reqOptions)\n\n      if (this.size != null && bytesUploaded !== this.size) {\n        const errMsg = `uploaded only ${bytesUploaded} of ${this.size} with status: ${response.statusCode}`\n        logger.error(errMsg, 'upload.multipart.mismatch.error')\n        throw new Error(errMsg)\n      }\n\n      let bodyURL = null\n      try {\n        bodyURL = JSON.parse(response.body)?.url\n      } catch {\n        // response.body can be undefined or an empty string\n        // in that case we ignore and continue.\n      }\n\n      return {\n        url: bodyURL,\n        extraData: { response: getRespObj(response), bytesUploaded },\n      }\n    } catch (err) {\n      logger.error(err, 'upload.multipart.error')\n      const errObj = isRecord(err) ? err : null\n      const response =","sourceCodeStart":827,"sourceCodeEnd":863,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/companion/src/server/Uploader.ts#L827-L863","documentation":"After Companion's multipart upload completes an HTTP PUT/POST via got, it compares the reported byte count with the expected size. If the connection closed after sending fewer bytes than the file size, it logs 'upload.multipart.mismatch.error' and throws this Error even though the server may have returned a success status.","triggerScenarios":"A network interruption or early connection close mid-upload so bytesUploaded < this.size; size computed differently from actual streamed bytes (e.g. size metadata mismatch from the provider download); proxies cutting the stream.","commonSituations":"Flaky networks between Companion and the destination endpoint, wrong file size metadata when piping a provider download into the Uploader, or chunked transfer edge cases.","solutions":["Retry the upload — transient network truncation is the most common cause","Verify the size metadata passed to Uploader matches the actual stream length (provider content-length vs streamed bytes)","Check intermediary proxies/load balancers for idle timeouts or request size limits on the destination URL"],"exampleFix":"// before\nconst uppy = new Uploader({ size: guessedSize, ... })\n\n// after\nconst uppy = new Uploader({ size: actualContentLengthFromProvider, ... })\n// plus: wrap upload in retry logic for transient truncation","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await uploader.upload() } catch (err) {\n  if (/uploaded only \\d+ of \\d+/.test(err.message)) { await backoffRetry(uploader.upload, { retries: 3 }) }\n  else throw err\n}","preventionTips":["Pass accurate size metadata (use provider content-length)","Add retry with exponential backoff around companion uploads","Check proxy timeouts on the receiving endpoint"],"tags":["companion","uploader","multipart","network","partial-upload"],"backgroundTag":"incomplete-upload-mismatch","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}