Почему в FastAPI возникает Broken Pipe и обрывается связь

Вопрос: Почему в FastAPI возникает Broken Pipe и обрывается связь с клиентом?

Линия поддержки
Линия поддержки Ответы на вопросы пользователей
6 апреля 2026

Показали, почему в FastAPI‑сервисе появляется BrokenPipeError и как это чинить, чтобы клиент не терял ответы посреди запроса.

Изображение записи

Комментарий пользователя

Здравствуйте! В проде в логах FastAPI периодически появляются ошибки BrokenPipeError, хотя в тестах такого нет. Клиент время от времени не получает полный ответ, а в моменте выглядит так, как будто сервис просто «оборвал» соединение. С чем это чаще всего связано и как это можно отловить, если вообще можно?

Евлахов Егор Пользователь

Ответ специалиста

Добрый день, Егор! В таком поведении чаще всего не виноват сам FastAPI, а случается это на границе между сервером и клиентом. Где‑то соединение закрывается раньше, чем успевает пройти весь ответ.

Broken Pipe обычно означает, что клиент уже закрыл TCP‑соединение, а сервер в этот момент до сих пор писал в сокет. В FastAPI это чаще всего вылезает в двух сценариях:

  • клиент ушел по таймауту и закрыл соединение (например, мобильный приложение, балансировщик, браузер, прокси или reverse‑proxy вроде NGINX/Ingress);
  • сервер долго стримит ответ (например, CSV, большой JSON или файловый архив), а клиент в середине процесса уходит или перезапускается.
  • Земцов Антон

    Земцов Антон

    Младший бэкенд-разработчик Python

Особенно это заметно под нагрузкой: клиенты не всегда ждут долго, а ваш Python‑код честно пишет в StreamingResponse или async‑генератор, не догадываясь, что уже никто не слушает.

В этой ситуации я обычно делаю простую вещь: аккуратно оборачиваю тяжелые эндпоинты и стриминг, так чтобы не было долгих «висящих» пишущих в сокет операций без контроля времени.

Например, вместо StreamingResponse, можно добавить явный контроль по времени и размеру части, а также не держать Socket открытым дольше, чем нужно:


      from fastapi import FastAPI
from fastapi.responses import StreamingResponse

app = FastAPI()

def generate_csv():
    for i in range(10_000):
        yield f"{i},value{i}\n"

@app.get("/big-data")
async def stream_csv():
    return StreamingResponse(generate_csv(), media_type="text/csv")

А еще это уменьшит нагрузку на event loop.

Следите за обновлениями, а если остались вопросы — ждем вас в Академии Selectel.