Import
import { bodyLimit } from 'hono/body-limit'
Usage
const app = new Hono()
app.post(
'/upload',
bodyLimit({
maxSize: 50 * 1024, // 50kb
onError: (c) => {
return c.text('overflow :(', 413)
},
}),
async (c) => {
const body = await c.req.parseBody()
if (body['file'] instanceof File) {
console.log(`Got file sized: ${body['file'].size}`)
}
return c.text('pass :)')
}
)
Options
The bodyLimit middleware accepts a BodyLimitOptions object:
The maximum body size allowed in bytes.
onError
(c: Context) => Response | Promise<Response>
Custom error handler invoked if the specified body size is exceeded. If not provided, returns a 413 Payload Too Large response with message “Payload Too Large”.
Signature
bodyLimit(options: BodyLimitOptions): MiddlewareHandler
Examples
Basic usage with size limit
app.post(
'/upload',
bodyLimit({ maxSize: 100 * 1024 }), // 100kb limit
async (c) => {
const body = await c.req.parseBody()
return c.json({ success: true })
}
)
Custom error handler
app.post(
'/upload',
bodyLimit({
maxSize: 1024 * 1024, // 1MB
onError: (c) => {
return c.json(
{ error: 'File too large', maxSize: '1MB' },
413
)
},
}),
async (c) => {
const body = await c.req.parseBody()
return c.json({ success: true })
}
)
Global body limit
const app = new Hono()
// Apply to all routes
app.use('*', bodyLimit({ maxSize: 1024 * 1024 }))
app.post('/upload', async (c) => {
const body = await c.req.parseBody()
return c.json({ success: true })
})
Behavior
- Checks
Content-Length header when available for early rejection
- Follows RFC 7230: Transfer-Encoding takes precedence over Content-Length
- For chunked transfers, streams the body and validates size incrementally
- Throws HTTPException with 413 status when size limit is exceeded
- Skips validation for GET and HEAD requests (no body expected)
- Returns early if no request body is present