alibaba/canal · error · CanalClientException

unexpected packet type when ack is expected

Error message

unexpected packet type when ack is expected

What it means

Error "unexpected packet type when ack is expected" thrown in alibaba/canal.

Source

Thrown at client/src/main/java/com/alibaba/otter/canal/client/impl/SimpleCanalConnector.java:188

                // encode passwd
                newPasswd = SecurityUtil.byte2HexStr(SecurityUtil.scramble411(password.getBytes(), seed.toByteArray()));
            }

            ClientAuth ca = ClientAuth.newBuilder()
                .setUsername(username != null ? username : "")
                .setPassword(ByteString.copyFromUtf8(newPasswd != null ? newPasswd : ""))
                .setNetReadTimeout(idleTimeout)
                .setNetWriteTimeout(idleTimeout)
                .build();
            writeWithHeader(Packet.newBuilder()
                .setType(PacketType.CLIENTAUTHENTICATION)
                .setBody(ca.toByteString())
                .build()
                .toByteArray());
            //
            Packet ack = Packet.parseFrom(readNextPacket());
            if (ack.getType() != PacketType.ACK) {
                throw new CanalClientException("unexpected packet type when ack is expected");
            }

            Ack ackBody = Ack.parseFrom(ack.getBody());
            if (ackBody.getErrorCode() > 0) {
                throw new CanalClientException("something goes wrong when doing authentication: "
                                               + ackBody.getErrorMessage());
            }

            connected = true;
            return new InetSocketAddress(channel.socket().getLocalAddress(), channel.socket().getLocalPort());
        } catch (IOException | NoSuchAlgorithmException e) {
            throw new CanalClientException(e);
        }
    }

    private void doDisconnect() throws CanalClientException {
        if (readableChannel != null) {
            quietlyClose(readableChannel);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Ensure getWithoutAck() and ack() calls are not interleaved concurrently from multiple threads on the same connector; the protocol is strictly request-response.
  2. Reconnect the connector and re-subscribe if the stream became desynchronized, then resume from the last acked position.

When it happens

Trigger: Thrown at client/src/main/java/com/alibaba/otter/canal/client/impl/SimpleCanalConnector.java:188 when the library encounters an invalid state.

Common situations: Ack expected but another packet type arrived. Discard the connection after logging the packet type; continuing on a desynchronized stream corrupts batch tracking.


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/17a68fc0cc6f9b70. Report an issue: GitHub.