{"record":{"id":"7503057764d3e010","repo":"toeverything/AFFiNE","slug":"upload-stopped-by-network-proxy-file-size-exceeds","errorCode":null,"errorMessage":"Upload stopped by network proxy: file size exceeds the set limit.","messagePattern":"Upload stopped by network proxy: file size exceeds the set limit\\.","errorType":"exception","errorClass":"OverSizeError","httpStatus":null,"severity":"error","filePath":"packages/common/nbstore/src/impls/cloud/blob.ts","lineNumber":217,"sourceCode":"              signal\n            );\n          }\n          await this.uploadViaGraphql(blob, signal);\n          return;\n        }\n      }\n\n      await this.uploadViaGraphql(blob, signal);\n    } catch (err) {\n      const userFriendlyError = UserFriendlyError.fromAny(err);\n      if (userFriendlyError.is('STORAGE_QUOTA_EXCEEDED')) {\n        throw new OverCapacityError();\n      }\n      if (userFriendlyError.is('BLOB_QUOTA_EXCEEDED')) {\n        throw new OverSizeError(this.humanReadableBlobSizeLimitCache);\n      }\n      if (userFriendlyError.is('CONTENT_TOO_LARGE')) {\n        throw new OverSizeError(\n          null,\n          'Upload stopped by network proxy: file size exceeds the set limit.'\n        );\n      }\n      throw err;\n    }\n  }\n\n  override async delete(key: string, permanently: boolean) {\n    await this.connection.gql({\n      query: deleteBlobMutation,\n      variables: { workspaceId: this.options.id, key, permanently },\n    });\n  }\n\n  override async release() {\n    await this.connection.gql({\n      query: releaseDeletedBlobsMutation,","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/common/nbstore/src/impls/cloud/blob.ts#L199-L235","documentation":"During CloudBlobStorage.set(), an HTTP 413 / CONTENT_TOO_LARGE response is rethrown as OverSizeError with the custom message 'Upload stopped by network proxy: file size exceeds the set limit.' The per-file and total quotas were fine, but a proxy between client and server (nginx client_max_body_size, Cloudflare 100MB free-tier cap, corporate proxy) rejected the request body.","triggerScenarios":"Uploading a file larger than a reverse proxy's body limit — nginx client_max_body_size defaults to 1MB; Cloudflare free plan caps at 100MB; the 413 status is converted to CONTENT_TOO_LARGE by HttpConnection.fetch (error 717) and then wrapped here.","commonSituations":"Self-hosted AFFiNE behind nginx without raising client_max_body_size to match AFFINE_BLOB_SIZE_LIMIT; deployments behind Cloudflare/CDN with a lower body cap than the app limit; corporate network proxies; limits inconsistent between layers so the app-level checks pass but the proxy still blocks.","solutions":["On self-hosted: align proxy limits with the app limit, e.g. nginx: client_max_body_size 100m; in every server{} / location that proxies uploads.","If behind Cloudflare/CDN, keep per-file limits below the CDN plan's body cap or upload via a direct/resumable route that bypasses the proxy.","Short-term: upload a smaller file.","Catch OverSizeError and distinguish the proxy case by message/code CONTENT_TOO_LARGE to hint 'network limit' rather than 'workspace limit'."],"exampleFix":"# before (nginx default)\n# client_max_body_size is 1m → uploads >1MB die with 413\n\n# after\nserver {\n  client_max_body_size 100m;  # >= AFFINE_BLOB_SIZE_LIMIT\n  location / {\n    proxy_pass http://affine;\n  }\n}","handlingStrategy":"try-catch","validationCode":"// Client cannot know proxy limits; approximate: keep files under min(app limit, known proxy limit)\nconst PROXY_LIMIT = 100 * 1024 * 1024; // e.g. CDN cap\nif (bytes.byteLength > Math.min(await blobStorage.getBlobSizeLimit(), PROXY_LIMIT)) throw new Error('too large');","typeGuard":"const isProxyOverSize = (e: unknown): boolean => e instanceof OverSizeError && e.message.includes('network proxy');","tryCatchPattern":"try { await blobStorage.set(rec); } catch (e) {\n  if (e instanceof OverSizeError) {\n    if (e.message.includes('network proxy')) toast('Network limit reached — contact your admin or use a smaller file.');\n    else toast('File exceeds the workspace size limit.');\n    return;\n  }\n  throw e;\n}","preventionTips":["nginx: set client_max_body_size >= AFFINE_BLOB_SIZE_LIMIT","Check every hop (CDN, WAF, reverse proxy) for body limits","Document the effective limit = min(app, proxy) for your deployment"],"tags":["blob-storage","upload","proxy","http-413","affine"],"backgroundTag":"http-413-request-entity-too-large","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}