diem/diem · error · NoiseHandshakeError

noise server: client peer id is malformed: {0}

Error message

noise server: client peer id is malformed: {0}

What it means

NoiseHandshakeError::InvalidClientPeerId is raised by the Noise server when the peer identity carried in the client's handshake payload cannot be parsed as a valid PeerId. The init message arrived but its self-reported identity is malformed, so the server refuses to authenticate the client.

Source

Thrown at network/src/noise/error.rs:37

    #[error("noise client: error sending client handshake init message: {0}")]
    ClientWriteFailed(io::Error),

    #[error(
        "noise client: error reading server handshake response message, server \
         probably rejected our handshake message: {0}"
    )]
    ClientReadFailed(io::Error),

    #[error("noise client: error flushing socket after writing: {0}")]
    ClientFlushFailed(io::Error),

    #[error("noise client: error finalizing secure connection: {0}")]
    ClientFinalizeFailed(NoiseError),

    #[error("noise server: error reading client handshake init message: {0}")]
    ServerReadFailed(io::Error),

    #[error("noise server: client peer id is malformed: {0}")]
    InvalidClientPeerId(String),

    #[error("noise server: detected self-dial: we're trying to connect to ourselves")]
    SelfDialDetected,

    #[error(
        "noise server: client {0}: client is expecting us to have a different \
         public key: {1}"
    )]
    ClientExpectingDifferentPubkey(ShortHexStr, String),

    #[error("noise server: client {0}: error parsing handshake init message: {1}")]
    ServerParseClient(ShortHexStr, NoiseError),

    #[error(
        "noise server: client {0}: known client peer id connecting to us with \
         unauthenticated public key: {1}"
    )]

View on GitHub (pinned to fc4714a8ea)

Solutions

  1. Update the client to the same protocol/types version as the server so the handshake payload encoding matches.
  2. Fix the client's peer id construction — ensure it is derived correctly (typically from the public key) and serialized per the expected format.
  3. Inspect the wrapped String ({0}) for the parse error detail to pinpoint the format problem.
  4. Rule out corruption by confirming both endpoints negotiate the same Noise protocol and framing.

Example fix

// before
let payload = HandshakeMsg { peer_id: PeerId::from_bytes(&raw[..16])? }; // truncated
// after
let payload = HandshakeMsg { peer_id: PeerId::from_public_key(&my_identity_key) };
Defensive patterns

Strategy: validation

Validate before calling

fn build_handshake_payload(key: &Ed25519PublicKey) -> Result<Vec<u8>, ParseError> {
    let peer_id = PeerId::from_public_key(key); // derive, never fabricate
    let mut buf = Vec::new();
    proto::encode(&HandshakeMsg { peer_id }, &mut buf)?;
    Ok(buf)
}

Try / catch

match accept_handshake(stream).await {
    Err(NoiseHandshakeError::InvalidClientPeerId(details)) => {
        error!("client sent malformed peer id: {} — likely protocol version mismatch", details);
        // reject connection, metric++ for version-mismatch
    }
    ok => ok.map(|_| ())?,
}

Prevention

When it happens

Trigger: A client sends a handshake init whose protobuf/payload contains a peer id that fails PeerId parsing/validation on the server (wrong format, wrong length, invalid encoding).

Common situations: Client built with mismatched diem-types/protocol versions producing an incompatible handshake payload; buggy custom client or test harness sending a fabricated peer id; corrupted handshake bytes in transit.

Understand the failure class

Related errors


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