kovidgoyal/kitty · error · ValueError

Unknown protocol in listen-on value: {spec}

Error message

Unknown protocol in listen-on value: {spec}

What it means

parse_address_spec() recognized a 'protocol:...' split but the protocol is neither 'unix' nor 'tcp'. The else-branch of the protocol check raises ValueError listing the offending spec. Only unix and tcp sockets are supported for remote control.

Source

Thrown at kitty/utils.py:413

        family = socket.AF_UNIX
        address = rest
        if address.startswith('@') and len(address) > 1:
            address = '\0' + address[1:]
        else:
            socket_path = address
    elif protocol in ('tcp', 'tcp6'):
        family = socket.AF_INET if protocol == 'tcp' else socket.AF_INET6
        if rest.startswith('['):  # ]
            host = rest[1:]
            host, sep, leftover = host.rpartition(']')
            _, port = leftover.rsplit(':', 1)
            if ':' in host and protocol == 'tcp':
                family = socket.AF_INET6
        else:
            host, port = rest.rsplit(':', 1)
        address = host, int(port)
    else:
        raise ValueError(f'Unknown protocol in listen-on value: {spec}')
    return family, address, socket_path


def parse_os_window_state(state: str) -> int:
    match state:
        case 'normal':
            return WINDOW_NORMAL
        case 'maximized':
            return WINDOW_MAXIMIZED
        case 'minimized':
            return WINDOW_MINIMIZED
        case 'fullscreen' | 'fullscreened':
            return WINDOW_FULLSCREEN
        case 'hidden':
            return WINDOW_HIDDEN
        case _:
            return WINDOW_NORMAL

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Change the protocol to unix: or tcp:
  2. For a file-descriptor-based socket, obtain it another way — kitty only supports unix/tcp here
  3. Check the exact spelling/case of the protocol prefix

Example fix

# before
--listen-on=udp:localhost:9901
# after
--listen-on=tcp:localhost:9901
Defensive patterns

Strategy: validation

Validate before calling

def valid_protocol(spec: str) -> bool:
    return spec.split(':', 1)[0] in ('unix', 'tcp')

Try / catch

try:
    fam, addr, path = parse_address_spec(spec)
except ValueError as e:
    if 'Unknown protocol' in str(e):
        spec = 'tcp' + spec[spec.index(':'):]
        fam, addr, path = parse_address_spec(spec)
    else:
        raise

Prevention

When it happens

Trigger: --listen-on=fd:3, --listen-on=udp:host:port, or any prefix other than unix/tcp.

Common situations: Assuming other socket types (udp, fd inheritance, tls) are supported; typo like 'UNIX:' (case matters); copying a listen string from another program's config.

Related errors


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