gofiber/fiber · error · ErrFileRead

file: failed to read file: %q: %w

Error message

file: failed to read file: %q: %w

What it means

Returned by Ctx.SaveFileToStorage when the uploaded file's declared Size (multipart.FileHeader.Size) already exceeds the configured BodyLimit, before any streaming read begins. It wraps ErrFileRead with the filename and fasthttp.ErrBodyTooLarge. This is the fast pre-check using the size advertised in the multipart header.

Source

Thrown at ctx.go:582

// SaveFileToStorage saves any multipart file to an external storage system.
func (c *DefaultCtx) SaveFileToStorage(fileheader *multipart.FileHeader, path string, storage Storage) error {
	if fileheader == nil {
		return ErrFileHeaderNil
	}

	file, err := fileheader.Open()
	if err != nil {
		return fmt.Errorf("%w: %q: %w", ErrFileOpen, fileheader.Filename, err)
	}
	defer file.Close() //nolint:errcheck // not needed

	maxUploadSize := c.app.config.BodyLimit
	if maxUploadSize <= 0 {
		maxUploadSize = DefaultBodyLimit
	}

	if fileheader.Size > 0 && fileheader.Size > int64(maxUploadSize) {
		return fmt.Errorf("%w: %q: %w", ErrFileRead, fileheader.Filename, fasthttp.ErrBodyTooLarge)
	}

	buf := bytebufferpool.Get()
	defer bytebufferpool.Put(buf)

	limitedReader := io.LimitReader(file, int64(maxUploadSize)+1)
	if _, err = buf.ReadFrom(limitedReader); err != nil {
		return fmt.Errorf("%w: %q: %w", ErrFileRead, fileheader.Filename, err)
	}

	if buf.Len() > maxUploadSize {
		return fmt.Errorf("%w: %q: %w", ErrFileRead, fileheader.Filename, fasthttp.ErrBodyTooLarge)
	}

	data := append([]byte(nil), buf.Bytes()...)

	if err := storage.SetWithContext(c.Context(), path, data, 0); err != nil {
		return fmt.Errorf("%w: %q to %q: %w", ErrFileStore, fileheader.Filename, path, err)

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Raise Config.BodyLimit to accommodate the maximum expected upload size.
  2. Validate file size on the client side before uploading.
  3. Use a reverse proxy (nginx) with client_max_body_size to reject oversized uploads earlier.
  4. Handle the error gracefully and return 413 Payload Too Large to the client.

Example fix

// before
app := fiber.New() // default body limit catches large uploads

// after
app := fiber.New(fiber.Config{
    BodyLimit: 50 * 1024 * 1024, // 50 MB
})
Defensive patterns

Strategy: validation

Validate before calling

// Reject oversized uploads before SaveFileToStorage
limit := int64(app.Config().BodyLimit)
if fileHeader.Size > limit {
    return fiber.ErrFileRead // or a custom 413 response
}

Try / catch

if err := c.SaveFileToStorage(fh, path, storage); err != nil {
    if errors.Is(err, fiber.ErrFileRead) && errors.Is(err, fasthttp.ErrBodyTooLarge) {
        return c.Status(fiber.StatusRequestEntityTooLarge).
            SendString("file too large")
    }
    return err
}

Prevention

When it happens

Trigger: A client uploads a file whose Content-Length/declared multipart size is larger than app.config.BodyLimit (or DefaultBodyLimit if unset). SaveFileToStorage compares fileheader.Size against the limit and rejects immediately.

Common situations: Forgetting to raise Config.BodyLimit for large uploads, a default 4MB limit catching legitimate media files, or a malicious oversized upload attempt.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/64d24ee555715098.json. Report an issue: GitHub.