Describe the bug
RequestReply can deadlock when duplicate reply events arrive for the same inflight request. The reply handler sends on pr.replyEvent while holding RLock(), while request cleanup needs the write lock to delete the inflight entry. If a second reply arrives before cleanup finishes, the second send can block and prevent cleanup from ever acquiring the write lock.
Expected behavior
Duplicate or late replies should be ignored or rejected without blocking inflight request cleanup. The handler should always clean up the inflight entry and return.
Actual behavior
The reply path can block while still holding the request-map read lock, and the original request path can then block indefinitely while trying to acquire the write lock for cleanup. The inflight entry remains uncleared and the request never completes normally.
To Reproduce
- Create an inflight request entry in
pkg/requestreply/ingress_handler.go.
- Start
handleNewEvent(...) so it waits on pr.replyEvent.
- Deliver two valid reply events with the same reply correlation ID in quick succession.
- Observe that one goroutine blocks on
pr.replyEvent <- event while the original request path blocks on deleteEvent(...), leaving the inflight entry uncleared.
A focused unit test can reproduce this by exercising handleNewEvent(...) and handleReplyEvent(...) concurrently with the same reply ID.
Knative release version
main at repository state assessed on 2026-07-15
Additional context
Relevant code:
pkg/requestreply/ingress_handler
pkg/requestreply/ingress_handler
Describe the bug
RequestReplycan deadlock when duplicate reply events arrive for the same inflight request. The reply handler sends onpr.replyEventwhile holdingRLock(), while request cleanup needs the write lock to delete the inflight entry. If a second reply arrives before cleanup finishes, the second send can block and prevent cleanup from ever acquiring the write lock.Expected behavior
Duplicate or late replies should be ignored or rejected without blocking inflight request cleanup. The handler should always clean up the inflight entry and return.
Actual behavior
The reply path can block while still holding the request-map read lock, and the original request path can then block indefinitely while trying to acquire the write lock for cleanup. The inflight entry remains uncleared and the request never completes normally.
To Reproduce
pkg/requestreply/ingress_handler.go.handleNewEvent(...)so it waits onpr.replyEvent.pr.replyEvent <- eventwhile the original request path blocks ondeleteEvent(...), leaving the inflight entry uncleared.A focused unit test can reproduce this by exercising
handleNewEvent(...)andhandleReplyEvent(...)concurrently with the same reply ID.Knative release version
mainat repository state assessed on 2026-07-15Additional context
Relevant code:
pkg/requestreply/ingress_handlerpkg/requestreply/ingress_handler