gofiber/fiber · error

failed to write response body to file: %w

Error message

failed to write response body to file: %w

What it means

Returned by Response.Save (client/response.go:170) when io.Copy fails while streaming the response body into the created file via BodyStream(). After the file is opened successfully, the copy can still fail mid-write — disk full, write I/O error, or the body stream itself errors during reading.

Source

Thrown at client/response.go:170

			if !errors.Is(err, fs.ErrNotExist) {
				return fmt.Errorf("failed to check directory: %w", err)
			}

			if err = os.MkdirAll(dir, 0o750); err != nil {
				return fmt.Errorf("failed to create directory: %w", err)
			}
		}

		// Create and write to file
		outFile, err := os.Create(file)
		if err != nil {
			return fmt.Errorf("failed to create file: %w", err)
		}
		defer func() { _ = outFile.Close() }() //nolint:errcheck // not needed

		// Use BodyStream() which handles both streaming and non-streaming cases
		if _, err = io.Copy(outFile, r.BodyStream()); err != nil {
			return fmt.Errorf("failed to write response body to file: %w", err)
		}

		return nil

	case io.Writer:
		// Use BodyStream() which handles both streaming and non-streaming cases
		if _, err := io.Copy(p, r.BodyStream()); err != nil {
			return fmt.Errorf("failed to write response body to writer: %w", err)
		}
		// Close the writer if it implements io.WriteCloser
		if pc, ok := p.(io.WriteCloser); ok {
			_ = pc.Close() //nolint:errcheck // not needed
		}

		return nil

	default:
		return ErrNotSupportSaveMethod

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Ensure sufficient free disk space for the full response body before saving.
  2. On error, remove the partial file so stale data is not consumed downstream.
  3. For large downloads, check Content-Length and fail early if it exceeds available space.
  4. Retry the request if the cause was a transient stream/network error.

Example fix

// before — partial file left on failure
if err := resp.Save(path); err != nil {
    log.Print(err) // stale partial file remains
}

// after — clean up partial output on copy failure
if err := resp.Save(path); err != nil {
    _ = os.Remove(path)
    return fmt.Errorf("save response: %w", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Fail early if available disk space is less than Content-Length.
func enoughSpace(path string, need int64) bool {
    var st unix.Statfs_t
    if unix.Statfs(path, &st) != nil { return true }
    return int64(st.Bavail)*int64(st.Bsize) >= need
}

Try / catch

if err := resp.Save(path); err != nil {
    _ = os.Remove(path) // discard partial file
    if strings.Contains(err.Error(), "write response body to file") {
        return fmt.Errorf("save failed (disk/stream): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling resp.Save(path) on a large response that fills the disk mid-copy, a body stream that errors partway (server closed connection, decompression error), or a filesystem write error (NFS failure, disk fault). The file may be left partially written.

Common situations: Disk full; network filesystem write failure; the server streams a huge body and the local disk cannot hold it; the response stream breaks mid-download; a decompressing BodyStream encounters corrupt compressed data.

Related errors


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