kovidgoyal/kitty · error

Ignoring encrypted rc command with unsupported protocol: {pc

Error message

Ignoring encrypted rc command with unsupported protocol: {pcmd.get("enc_proto")}

What it means

An encrypted remote-control command specified an enc_proto value different from the RC_ENCRYPTION_PROTOCOL_VERSION kitty supports, so it is dropped. This guards against protocol-version mismatch between client and server.

Source

Thrown at kitty/remote_control.py:60

def encode_response_for_peer(response: Any) -> bytes:
    return b'\x1bP@kitty-cmd' + json.dumps(response).encode('utf-8') + b'\x1b\\'


def parse_cmd(serialized_cmd: memoryview, encryption_key: EllipticCurveKey) -> dict[str, Any]:
    # See https://github.com/python/cpython/issues/74379 for why we cant use
    # memoryview directly :((
    try:
        pcmd = json.loads(bytes(serialized_cmd))
    except Exception:
        log_error('Failed to parse JSON payload of remote command, ignoring it')
        return {}
    if not isinstance(pcmd, dict) or 'version' not in pcmd:
        log_error('JSON payload of remote command is invalid, must be an object with a version field')
        return {}
    pcmd.pop('password', None)
    if 'encrypted' in pcmd:
        if pcmd.get('enc_proto', '1') != RC_ENCRYPTION_PROTOCOL_VERSION:
            log_error(f'Ignoring encrypted rc command with unsupported protocol: {pcmd.get("enc_proto")}')
            return {}
        pubkey = pcmd.get('pubkey', '')
        if not pubkey:
            log_error('Ignoring encrypted rc command without a public key')
        d = AES256GCMDecrypt(encryption_key.derive_secret(base64.b85decode(pubkey)), base64.b85decode(pcmd['iv']), base64.b85decode(pcmd['tag']))
        data = d.add_data_to_be_decrypted(base64.b85decode(pcmd['encrypted']), True)
        pcmd = json.loads(data)
        if not isinstance(pcmd, dict) or 'version' not in pcmd:
            return {}
        delta = time_ns() - pcmd.pop('timestamp')
        if abs(delta) > 5 * 60 * 1e9:
            log_error(
                f'Ignoring encrypted rc command with timestamp {delta / 1e9:.1f} seconds from now.'
                ' Could be an attempt at a replay attack or an incorrect clock on a remote machine.'
            )
            return {}
    return pcmd

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Upgrade kitty and kittens together so both use the same RC encryption protocol version
  2. Use matching kitten binary from the same install as the running kitty
Defensive patterns

Strategy: validation

Validate before calling

from kitty.constants import RC_ENCRYPTION_PROTOCOL_VERSION  # match on both sides
pcmd['enc_proto'] = RC_ENCRYPTION_PROTOCOL_VERSION

Prevention

When it happens

Trigger: parse_cmd sees 'encrypted' in the payload and pcmd['enc_proto'] (default '1') != RC_ENCRYPTION_PROTOCOL_VERSION — e.g. newer kitten client talking to older kitty.

Common situations: kitten/kitty version skew after a partial upgrade, or a custom client hard-coding the wrong enc_proto.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/35fde4cb1bdd0d83. Report an issue: GitHub.