diem/diem · warning · StreamError

Client#{0} is closed

Error message

Client#{0} is closed

What it means

`StreamError::ClientAlreadyClosed(u64)` indicates an operation was attempted on a streaming-RPC client identified by the given id, but that client's stream is already closed. Once a client disconnects or its stream is torn down, further sends/operations on it are rejected with this error.

Source

Thrown at json-rpc/src/stream_rpc/errors.rs:10

// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use thiserror::Error;

#[derive(Debug, Error)]
pub enum StreamError {
    #[error("Could not convert {0} to string")]
    CouldNotStringifyMessage(String),
    #[error("Client#{0} is closed")]
    ClientAlreadyClosed(u64),
    #[error("Received disconnect request message from client")]
    ClientWantsToDisconnect,
    #[error("Transport error: {0}")]
    TransportError(String),
}

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Treat it as benign: check client liveness before sending and skip/log when already closed.
  2. Track client connection state in a registry and remove closed clients from notification fan-out lists.
  3. Synchronize close/send paths (e.g., use a single owner task per client) to avoid races between closing and sending.
  4. Ensure clients reconnect and re-subscribe; the id in the message identifies the stale client.
Defensive patterns

Strategy: try-catch

Type guard

fn is_client_closed(err: &StreamError, client_id: u64) -> bool {
    matches!(err, StreamError::ClientAlreadyClosed(id) if *id == client_id)
}

Try / catch

match notify_client(client_id, &msg) {
    Err(StreamError::ClientAlreadyClosed(id)) => {
        debug!("client#{} already closed; dropping notification", id);
        registry.remove(id);
    }
    Err(e) => error!("notify failed: {}", e),
    Ok(_) => {}
}

Prevention

When it happens

Trigger: Sending a message or notification to a subscribed client after it disconnected or its channel was dropped/closed; racing a close with an in-flight send on the stream-rpc layer.

Common situations: Clients dropping WebSocket connections mid-subscription; server-side timeouts closing streams while notifications are still queued; double-close attempts during shutdown.

Related errors


AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04). Data as JSON: /api/errors/b9aeb472f9de38a9. Report an issue: GitHub.