libp2p / libp2p/rust-libp2p

Dial requests in `stream` behaviour are silently dropped

Open
#6,157 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.6k
Forks
1.3k
Avg merge
8h 47m
Merged PRs (30d)
19

Description

Summary

I'm struggling to understand why the stream behavior calls try_send without handling the result here.
In our use case with hundreds of streams opened per second, it becomes a serious problem — some of the requested streams never trigger a dial, so nothing happens until a timeout on the caller's side.

Expected behavior

If a stream couldn't be opened, at least an error should be returned to the caller. Ideally, the behaviour should handle it itself and, e.g. queue the request for later, but I can see why it's problematic.

Actual behavior

Control::open_stream never returns, although some resources were allocated.

Relevant log output
2025-09-03T10:56:22.581481Z DEBUG sqd_network_transport::behaviour::stream_client: Opening stream to 12D3KooWFjzbi2MNkVpEDtdybAFuvixmTUzzijVNXxSo4cxAgpoR
2025-09-03T10:56:22.581514Z DEBUG libp2p_stream::control: Requesting new stream peer=12D3KooWFjzbi2MNkVpEDtdybAFuvixmTUzzijVNXxSo4cxAgpoR
2025-09-03T10:56:22.581546Z DEBUG libp2p_stream::shared: Not connected to peer, initiating dial peer=12D3KooWFjzbi2MNkVpEDtdybAFuvixmTUzzijVNXxSo4cxAgpoR

...Nothing mentioning "12D3KooWFjzbi2MNkVpEDtdybAFuvixmTUzzijVNXxSo4cxAgpoR" on TRACE level

2025-09-03T10:56:32.584019Z DEBUG sqd_network_transport::behaviour::stream_client: Connection to 12D3KooWFjzbi2MNkVpEDtdybAFuvixmTUzzijVNXxSo4cxAgpoR timed out
Possible Solution

A few options I see:

  • Just use an unbounded channel. It might be the best option if the backpressure can't be correctly propagated.
  • Await until the dial request is sent, propagating backpressure to the client to pause new requests until the behaviour is polled unblocking the channel.
  • If none of the above is possible, at least return an error to the client, saying that there are too many concurrent dial attempts.
Version

0.55

Would you like to work on fixing this bug?

Yes

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at protocols/stream/src/shared.rs around the try_send call linked in the issue, then trace how Control::open_stream handles dial requests and channel backpressure. Reproduce the high-rate stream-opening case described in the logs and determine how a failed request should be surfaced or retained; done means callers no longer wait indefinitely when a dial request cannot be sent.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.