ytdl-org/youtube-dl · error · InvalidVersionError

Invalid response version from server. Expected {0:02x} got {

Error message

Invalid response version from server. Expected {0:02x} got {1:02x}

What it means

Raised as InvalidVersionError by sockssocket._check_response_version when the first byte of the server's response does not match the protocol-expected version byte (e.g. 0x05 for SOCKS5 handshake, 0x01 for the user-auth sub-negotiation). The socket is closed first, then the error reports expected vs got in hex.

Source

Thrown at youtube_dl/socks.py:141

        while len(data) < cnt:
            cur = self.recv(cnt - len(data))
            if not cur:
                raise EOFError('{0} bytes missing'.format(cnt - len(data)))
            data += cur
        return data

    def _recv_bytes(self, cnt):
        data = self.recvall(cnt)
        return compat_struct_unpack('!{0}B'.format(cnt), data)

    @staticmethod
    def _len_and_data(data):
        return compat_struct_pack('!B', len(data)) + data

    def _check_response_version(self, expected_version, got_version):
        if got_version != expected_version:
            self.close()
            raise InvalidVersionError(expected_version, got_version)

    def _resolve_address(self, destaddr, default, use_remote_dns):
        try:
            return socket.inet_aton(destaddr)
        except socket.error:
            if use_remote_dns and self._proxy.remote_dns:
                return default
            else:
                return socket.inet_aton(socket.gethostbyname(destaddr))

    def _setup_socks4(self, address, is_4a=False):
        destaddr, port = address

        ipaddr = self._resolve_address(destaddr, SOCKS4_DEFAULT_DSTIP, use_remote_dns=is_4a)

        packet = compat_struct_pack('!BBH', SOCKS4_VERSION, Socks4Command.CMD_CONNECT, port) + ipaddr

        username = (self._proxy.username or '').encode('utf-8')

View on GitHub (pinned to 956b8c5855)

Solutions

  1. Test the endpoint with curl to identify what it actually speaks: 'curl -v -x socks5h://host:port ...' vs '-x http://host:port'
  2. Change the --proxy scheme to match the real protocol (http://, socks4://, socks5://)
  3. Verify the port number against the proxy's configuration
  4. If the server is SOCKS4-only, use socks4:// or upgrade the server to SOCKS5

Example fix

# before
youtube-dl --proxy 'socks5://proxy.example.com:3128' URL  # 3128 = HTTP proxy
# after
youtube-dl --proxy 'http://proxy.example.com:3128' URL
Defensive patterns

Strategy: validation

Validate before calling

import socket

def endpoint_speaks_socks5(host, port, timeout=3):
    s = socket.create_connection((host, port), timeout)
    s.sendall(b'\x05\x01\x00')          # greeting: 1 method, no-auth
    resp = s.recv(2)
    s.close()
    return resp[:1] == b'\x05'            # server must echo version 5

assert endpoint_speaks_socks5(host, port), 'not a SOCKS5 server — fix scheme/port'

Try / catch

try:
    ydl.download([url])
except Exception as e:
    if type(e).__name__ == 'InvalidVersionError':
        raise SystemExit('Proxy is not SOCKS5 on this port; check --proxy scheme and port')
    raise

Prevention

When it happens

Trigger: Talking SOCKS5 to something that is not a SOCKS5 server: an HTTP CONNECT proxy (responds 'HTTP/1.1 ...' — first byte 0x48), a SOCKS4-only server, or any service whose greeting does not start with the version byte. Also fires in the sub-auth step if the server sends an unexpected auth reply version.

Common situations: --proxy socks5:// used against an HTTP proxy port; SOCKS4 server addressed as socks5; misconfigured port forwarding to the wrong local service; some proxies that banner-greet with text.

Related errors


AI-assisted analysis of ytdl-org/youtube-dl@956b8c5855 (2026-08-14). Data as JSON: /api/errors/a406ef7d93ca61be. Report an issue: GitHub.