diem/diem · error · io::Error
MemoryListener unknown error
Error message
MemoryListener unknown error
What it means
MemoryListener (the in-memory socket listener used by memsocket for tests/simulations) is backed by a stream of incoming connections. When that stream is closed and returns None — i.e. the listener was dropped or the socket registry shut down — poll_accept converts the termination into an io::Error with this message, since std's Listener API has no graceful 'closed' signal.
Source
Thrown at network/memsocket/src/lib.rs:187
/// while let Some(stream) = incoming.next().await {
/// match stream {
/// Ok(stream) => {
/// println!("new connection!");
/// },
/// Err(e) => { /* connection failed */ }
/// }
/// }
/// # Ok(())}
/// ```
pub fn incoming(&mut self) -> Incoming<'_> {
Incoming { inner: self }
}
fn poll_accept(&mut self, context: &mut Context) -> Poll<Result<MemorySocket>> {
match Pin::new(&mut self.incoming).poll_next(context) {
Poll::Ready(Some(socket)) => Poll::Ready(Ok(socket)),
Poll::Ready(None) => {
let err = Error::new(ErrorKind::Other, "MemoryListener unknown error");
Poll::Ready(Err(err))
}
Poll::Pending => Poll::Pending,
}
}
}
/// Stream returned by the `MemoryListener::incoming` function representing the
/// stream of sockets received from a listener.
#[must_use = "streams do nothing unless polled"]
#[derive(Debug)]
pub struct Incoming<'a> {
inner: &'a mut MemoryListener,
}
impl<'a> Stream for Incoming<'a> {
type Item = Result<MemorySocket>;
View on GitHub (pinned to fc4714a8ea)
Solutions
- Ensure the accept loop is stopped/dropped before the MemoryListener or registry is torn down
- Hold a clone of the listener/registry for the lifetime of the accept task
- Treat this error as 'listener closed' and exit the accept loop instead of retrying
- If seen in tests, fix shutdown ordering (abort server tasks before dropping sockets)
Example fix
// before
loop { let conn = listener.accept().await?; spawn(handle(conn)); }
// after
loop {
match listener.accept().await {
Ok(conn) => spawn(handle(conn)),
Err(e) if e.kind() == ErrorKind::Other && e.to_string().contains("MemoryListener unknown error") => break, // listener closed
Err(e) => return Err(e.into()),
}
} Defensive patterns
Strategy: try-catch
Try / catch
// treat the error as listener-closed and stop accepting
match listener.accept().await {
Ok(socket) => /* handle */ ,
Err(e) if e.to_string().contains("MemoryListener unknown error") => break,
Err(e) => return Err(e.into()),
} Prevention
- Drop MemoryListeners only after their accept tasks are stopped
- Keep the memsocket registry alive for the full test lifetime
- Check shutdown ordering in test teardown (abort tasks before dropping sockets)
- Map this error explicitly in code that reuses memsocket for simulations
When it happens
Trigger: Calling accept() on a MemoryListener whose underlying incoming stream has ended: the MemorySocket listener was dropped, the shared incoming channel was closed, or the memsocket registry shut down while a task was still accepting.
Common situations: Async test harness drops the socket registry or listener while a server task is still polling accept; simulation code that closes listeners without first stopping accept loops; shutdown-ordering races in tests using network builders built on memsocket.
Related errors
- Failed to read '{0}' from JSON-RPC: {1}
- {0} timed out: {1}
- Should have generated a trusted peer set
- Error: could not find an available port
- not enough blocks returned, expect {}, get {}
AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04).
Data as JSON: /api/errors/1cfd3178b7ef7d36.
Report an issue: GitHub.