hcengineering/platform · error

File too large

Error message

File too large

What it means

The message 'File too large' is returned with HTTP 413 by PUT /api/v1/blob when the client-declared size query parameter exceeds MAX_FILE_SIZE. The server validates the declared size up-front, before streaming the request body to external storage, to reject oversized uploads early.

Source

Thrown at pods/server/src/server_http.ts:341

        if (authHeader === undefined) {
          res.status(401).end(JSON.stringify({ error: 'Unauthorized' }))
          return
        }

        const token = authHeader.split(' ')[1]
        const wsIds = await getWorkspaceIds(token)

        if (wsIds.uuid == null) {
          res.status(403).end(JSON.stringify({ error: 'No workspace found' }))
          return
        }

        const name = req.query.name as string
        const contentType = req.query.contentType as string
        const size = parseInt((req.query.size as string) ?? '-1')

        if (size > MAX_FILE_SIZE) {
          res.writeHead(413, { 'Content-Type': 'application/json', ...KEEP_ALIVE_HEADERS })
          res.end(JSON.stringify({ error: 'File too large' }))
          return
        }
        if (Number.isNaN(size)) {
          ctx.error('/api/v1/blob put error', {
            message: 'invalid NaN file size',
            name,
            workspace: wsIds.uuid
          })
          res.writeHead(404, { ...KEEP_ALIVE_HEADERS })
          res.end()
          return
        }
        await ctx.with(
          'storage upload',
          {},
          async (ctx) => {
            await externalStorage.put(

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the declared size query param and chunk or compress the file to stay under MAX_FILE_SIZE
  2. Raise MAX_FILE_SIZE in server configuration if legitimate large uploads are required
  3. Ensure the client reports the size in bytes, not KB/MB
  4. Upload in multiple smaller blobs and reassemble client-side

Example fix

// before
const size = fs.statSync(path).size
fetch(`/api/v1/blob?name=${name}&size=${size}`, { method: 'PUT', body: stream }) // 413 if too big
// after
if (size > MAX_FILE_SIZE) throw new Error('Split or compress file before upload')
fetch(`/api/v1/blob?name=${name}&size=${size}`, { method: 'PUT', body: stream })
Defensive patterns

Strategy: validation

Validate before calling

const size = fs.statSync(filePath).size
if (size > MAX_FILE_SIZE) throw new Error(`file ${size} exceeds limit ${MAX_FILE_SIZE}; split or compress first`)

Type guard

const isWithinLimit = (size: unknown): size is number =>
  typeof size === 'number' && Number.isFinite(size) && size <= MAX_FILE_SIZE

Try / catch

const res = await fetch(blobUrl, { method: 'PUT', body })
if (res.status === 413) {
  const body = await res.json().catch(() => null)
  console.error('upload rejected:', body?.error)
}

Prevention

When it happens

Trigger: PUT /api/v1/blob?name=...&size=N where N (parsed from the size query param) is greater than MAX_FILE_SIZE; also size omitted yields -1 which is allowed, but any declared positive size above the cap triggers this.

Common situations: Uploading large video/model files to a workspace; client passing size in different units (KB vs bytes); MAX_FILE_SIZE lowered via config while clients still send old large files.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/2b447d010b045693. Report an issue: GitHub.