Skip to content

cannot connect from IPv6 Link-Local IP due to missing zone-index #664

@9001

Description

@9001

With pyftpdlib listening on IPv6, if a client connects from an IPv6 Link-Local IP [fe80:...] the connection will fail and the server logs the following:

$ python3 -m pyftpdlib -Vi ::
[I 2025-08-21 19:48:20] concurrency model: async
[I 2025-08-21 19:48:20] masquerade (NAT) address: None
[I 2025-08-21 19:48:20] passive ports: None
[I 2025-08-21 19:48:20] >>> starting FTP server on :::2121, pid=1033053 <<<
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[] FTP session opened (connect)
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[anonymous] USER 'anonymous' logged in.
[E 2025-08-21 19:48:23] unhandled exception in instance <FTPHandler(id=140507583070288, addr='fe80::5054:ff:fe2a:b374:42344', user='anonymous')>
    Traceback (most recent call last):
      File "/usr/lib/python3.13/site-packages/asyncore/__init__.py", line 83, in read
        obj.handle_read_event()
        ~~~~~~~~~~~~~~~~~~~~~^^
      File "/usr/lib/python3.13/site-packages/asyncore/__init__.py", line 420, in handle_read_event
        self.handle_read()
        ~~~~~~~~~~~~~~~~^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/ioloop.py", line 967, in handle_read
        asynchat.async_chat.handle_read(self)
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
      File "/usr/lib/python3.13/site-packages/asynchat/__init__.py", line 171, in handle_read
        self.found_terminator()
        ~~~~~~~~~~~~~~~~~~~~~^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1574, in found_terminator
        self.pre_process_command(line, cmd, arg)
        ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1693, in pre_process_command
        self.process_command(cmd, arg, **kwargs)
        ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 1704, in process_command
        method(*args, **kwargs)
        ~~~~~~^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 2253, in ftp_EPSV
        self._make_epasv(extmode=True)
        ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 2152, in _make_epasv
        self._dtp_acceptor = self.passive_dtp(self, extmode)
                             ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
      File "/usr/lib/python3.13/site-packages/pyftpdlib/handlers.py", line 420, in __init__
        af = self.bind_af_unspecified((local_ip, 0))
      File "/usr/lib/python3.13/site-packages/pyftpdlib/ioloop.py", line 1072, in bind_af_unspecified
        raise OSError(err)
    OSError: [Errno 22] Invalid argument
[I 2025-08-21 19:48:23] fe80::5054:ff:fe2a:b374:42344-[anonymous] FTP session closed (disconnect).

the issue can be reproduced by connecting from curl:

curl 'ftp://[fe80::5054:ff:fe2a:b374%virhost0]:2121/' 

in the curl-command, because the IPv6-address is Link-Local, the IP fe80::5054:ff:fe2a:b374 must be suffixed with the zone index, such as the name of the NIC which holds the address (virhost0 as above), otherwise curl will complain that the address is invalid and refuse to connect.

conversely, this is also the issue on pyftpdlib's side; the value of local_ip in self.bind_af_unspecified((local_ip, 0)) is just the client-IP itself, without the required zone-index suffix, so python throws the exception.

BTW, thank you for such an excellent library! it has been serving me very well, to the point that I haven't found a bug until just now :-)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions