kovidgoyal/kitty · error
Ignoring encrypted rc command without a public key
Error message
Ignoring encrypted rc command without a public key
What it means
An encrypted remote-control command lacks the 'pubkey' field, so kitty cannot derive the shared secret to decrypt it. Note the code logs and continues (which will then fail on b85decode of the empty pubkey) — the message signals a malformed encrypted payload.
Source
Thrown at kitty/remote_control.py:64
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
class CMDChecker:
def __call__(self, pcmd: dict[str, Any], window: Optional['Window'], from_socket: bool, extra_data: dict[str, Any]) -> bool | None:
return FalseView on GitHub (pinned to 6d5d0c4406)
Solutions
- Include the base85-encoded ephemeral public key in the 'pubkey' field
- Prefer using kitten's built-in ECDH handshake instead of constructing encrypted commands manually
Defensive patterns
Strategy: validation
Validate before calling
assert pcmd.get('encrypted') is True and pcmd.get('pubkey'), 'encrypted payload needs pubkey' Type guard
def is_complete_encrypted_cmd(p: dict) -> bool:
return all(k in p for k in ('pubkey', 'iv', 'tag', 'encrypted')) Prevention
- Let kitten perform the ECDH handshake rather than building encrypted payloads manually
When it happens
Trigger: pcmd contains 'encrypted': true but no 'pubkey' key, hitting the `if not pubkey` branch in parse_cmd.
Common situations: Hand-built encrypted RC payloads missing fields, or a buggy/older client that omits pubkey.
Related errors
- KITTY_PUBLIC_KEY has unknown version, if you are running on
- Ignoring encrypted rc command with unsupported protocol: {pc
- This should be run as kitten icat
- This should be run as `kitten notify ...`
- Remote control not enabled, this kitten should be run via a
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/5268f0859a865fde.
Report an issue: GitHub.