toeverything/AFFiNE · error · OverSizeError

Upload stopped by network proxy: file size exceeds the set l

Error message

Upload stopped by network proxy: file size exceeds the set limit.

What it means

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.

Source

Thrown at packages/common/nbstore/src/impls/cloud/blob.ts:217

              signal
            );
          }
          await this.uploadViaGraphql(blob, signal);
          return;
        }
      }

      await this.uploadViaGraphql(blob, signal);
    } catch (err) {
      const userFriendlyError = UserFriendlyError.fromAny(err);
      if (userFriendlyError.is('STORAGE_QUOTA_EXCEEDED')) {
        throw new OverCapacityError();
      }
      if (userFriendlyError.is('BLOB_QUOTA_EXCEEDED')) {
        throw new OverSizeError(this.humanReadableBlobSizeLimitCache);
      }
      if (userFriendlyError.is('CONTENT_TOO_LARGE')) {
        throw new OverSizeError(
          null,
          'Upload stopped by network proxy: file size exceeds the set limit.'
        );
      }
      throw err;
    }
  }

  override async delete(key: string, permanently: boolean) {
    await this.connection.gql({
      query: deleteBlobMutation,
      variables: { workspaceId: this.options.id, key, permanently },
    });
  }

  override async release() {
    await this.connection.gql({
      query: releaseDeletedBlobsMutation,

View on GitHub (pinned to b4c8548c09)

Solutions

  1. 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.
  2. 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.
  3. Short-term: upload a smaller file.
  4. Catch OverSizeError and distinguish the proxy case by message/code CONTENT_TOO_LARGE to hint 'network limit' rather than 'workspace limit'.

Example fix

# before (nginx default)
# client_max_body_size is 1m → uploads >1MB die with 413

# after
server {
  client_max_body_size 100m;  # >= AFFINE_BLOB_SIZE_LIMIT
  location / {
    proxy_pass http://affine;
  }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Client cannot know proxy limits; approximate: keep files under min(app limit, known proxy limit)
const PROXY_LIMIT = 100 * 1024 * 1024; // e.g. CDN cap
if (bytes.byteLength > Math.min(await blobStorage.getBlobSizeLimit(), PROXY_LIMIT)) throw new Error('too large');

Type guard

const isProxyOverSize = (e: unknown): boolean => e instanceof OverSizeError && e.message.includes('network proxy');

Try / catch

try { await blobStorage.set(rec); } catch (e) {
  if (e instanceof OverSizeError) {
    if (e.message.includes('network proxy')) toast('Network limit reached — contact your admin or use a smaller file.');
    else toast('File exceeds the workspace size limit.');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/7503057764d3e010. Report an issue: GitHub.