Skip to content

Crash when closing a session/response during an incomplete streaming request (SSE/stream mode) #675

@MurkyWang

Description

@MurkyWang

Hi, I encountered a reproducible crash in curl_cffi when using Session.get(..., stream=True) to read from a long-lived streaming endpoint (SSE or chunked stream).

Summary of the issue

When reading only the first line of a streaming response, if the stream has not fully initialized or not exited normally, calling:

response.close()
session.close()

will occasionally cause a hard crash (Python process exits without exception, likely a segfault from libcurl).

This happens only when the streaming connection is not cleanly closed on the server side or when the read is interrupted early. It seems the internal curl easy handle or connection state is still “half-initialized”, and freeing it leads to an invalid pointer free.

Minimal Reproduction

from curl_cffi import requests
import time

session = requests.Session()
session.keep_alive = True

response = session.get(url, stream=True, timeout=1.5)

# Read only the first event/chunk
it = response.iter_lines()
chunk = next(it)

# ❗ Crash happens here
response.close()
session.close()

If the server does not close the stream gracefully, or the stream initialization is incomplete, calling close() crashes the interpreter.

Expected behavior

Closing a session or response should never crash Python, even if the underlying curl handle is in a partially initialized or interrupted streaming state.

Actual behavior

The Python interpreter exits abruptly (no Python exception, likely segmentation fault from curl handle cleanup).

Additional Notes

This only affects stream=True long-lived endpoints (SSE, chunked streams).

Not closing the response/session avoids the crash, but leads to resource leak.

Setting keep_alive=False reduces but does not eliminate the crash.

The issue likely occurs during cleanup of an active or half-initialized libcurl easy handle.

Environment

curl_cffi version: 0.13.0

Python version: 3.13.9

Platform: Windows 11

Endpoint: long-lived SSE/streaming API (never ends unless interrupted)

Request

Is it possible to make response.close() and session.close() safe in all cases by ensuring that any partially initialized curl handle is put into a valid cleanup state before being freed?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions