apache/cassandra · warning

Failed to properly handshake with peer

Error message

Failed to properly handshake with peer {}. Closing the channel. Invalid legacy protocol magic.

What it means

Logged when the Netty channel exception handler detects that a peer sent an internode handshake whose 'magic' value does not match any legacy protocol version Cassandra can speak. The connection is closed via failHandshake because the peer is either not a Cassandra node, runs a wildly incompatible major version, or is a non-Cassandra process on the internode port.

Solutions

  1. Verify both endpoints run compatible Cassandra versions for the cluster (roll upgrades within supported versions).
  2. Check that the peer really is a Cassandra node and that the address:storage_port is correct in cassandra.yaml.
  3. Inspect internode_error_reporting_exclusions and health-checkers: exclude LB/probe IPs that hit the storage port.
  4. Run nodetool gossipinfo / verify network connectivity and that no other service occupies storage_port.
  5. If the peer cannot be made compatible, firewall it off or stop it from connecting.
Defensive patterns

Strategy: validation

Validate before calling

// Before pointing any process at storage_port, verify it is a Cassandra peer:
// nodetool gossipinfo | grep <peer-ip>
// netstat -tlnp | grep 7000  (confirm only Cassandra binds the port)

Try / catch

// Server-side: this is logged, not thrown to user code.
// Suppress noise from known non-Cassandra probes via cassandra.yaml:
// internode_error_reporting_exclusions: [<lb-ip>, <probe-ip>]

Prevention

When it happens

Trigger: exceptionCaught fires with a root cause of Message.InvalidLegacyProtocolMagic during the internode connection handshake; happens when a peer connects that cannot deserialize the initial handshake frame.

Common situations: Misconfigured clients pointed at the storage_port (e.g. a client using native transport port as internode), mixed-version clusters crossing incompatible majors, firewalls/proxies or load balancers health-checking the internode port, or a non-Cassandra service bound to the same port.

Understand the failure class

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/1a3e4f438ff07b39. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/net/InboundConnectionInitiator.java:396

        {
            return ctx.pipeline().get(SslHandler.class) != null;
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
        {
            exceptionCaught(ctx.channel(), cause);
        }

        private void exceptionCaught(Channel channel, Throwable cause)
        {
            final SocketAddress remoteAddress = channel.remoteAddress();
            boolean reportingExclusion = DatabaseDescriptor.getInternodeErrorReportingExclusions().contains(remoteAddress);

            if (reportingExclusion)
                logger.debug("Excluding internode exception for {}; address contained in internode_error_reporting_exclusions", remoteAddress, cause);
            else if (cause != null && Throwables.getRootCause(cause) instanceof Message.InvalidLegacyProtocolMagic && DatabaseDescriptor.getInvalidLegacyProtocolMagicNoSpamEnabled())
                noSpam5m.warn("Failed to properly handshake with peer {}. Closing the channel. Invalid legacy protocol magic.", ((InetSocketAddress) channel.remoteAddress()).getHostName());
            else
                logger.error("Failed to properly handshake with peer {}. Closing the channel.", remoteAddress, cause);

            try
            {
                failHandshake(channel);
            }
            catch (Throwable t)
            {
                if (!reportingExclusion)
                    logger.error("Unexpected exception in {}.exceptionCaught", this.getClass().getSimpleName(), t);
            }
        }

        private void failHandshake(ChannelHandlerContext ctx)
        {
            failHandshake(ctx.channel());
        }

View on GitHub (pinned to 88fd0f6a0e)