libp2p / libp2p/py-libp2p

ipv6 error: MultiAddr '/ip6/::1/tcp/0' does not contain protocol ip4

Open
#1,111 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
624
Forks
256
Avg merge
1d 34m
Merged PRs (30d)
47

Description

Summary

When I try to create peers that communicate over ipv6 I get an error using libp2p 0.5.0:

    |   File "/home/tim/dev/p2ptest/env/lib/python3.12/site-packages/libp2p/transport/tcp/tcp.py", line 91, in listen
    |     ip4_host_str = maddr.value_for_protocol("ip4")
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "/home/tim/dev/p2ptest/env/lib/python3.12/site-packages/multiaddr/multiaddr.py", line 293, in value_for_protocol
    |     raise exceptions.ProtocolLookupError(proto, str(self))
    | multiaddr.exceptions.ProtocolLookupError: MultiAddr '/ip6/::1/tcp/0' does not contain protocol Protocol(code=4, name='ip4', codec='ip4')

My minimal example:

import argparse

import trio
import multiaddr

from libp2p import (
    InsecureTransport,
    PLAINTEXT_PROTOCOL_ID,
    TProtocol,
    create_new_ed25519_key_pair,
    new_host,
)
from libp2p.peer.peerinfo import info_from_p2p_addr
from libp2p.peer.peerstore import PeerStore
from libp2p.tools.async_service import background_trio_service


def make_plaintext_host(listen_addrs=None):
    key_pair = create_new_ed25519_key_pair()
    peerstore = PeerStore()
    sec_opt = {
        TProtocol(PLAINTEXT_PROTOCOL_ID): InsecureTransport(
            key_pair, peerstore=peerstore
        )
    }
    return new_host(
        key_pair=key_pair,
        sec_opt=sec_opt,
        peerstore_opt=peerstore,
        listen_addrs=listen_addrs,
    )


async def main(use_ipv4: bool):
    if use_ipv4:
        listen_addr = multiaddr.Multiaddr("/ip4/127.0.0.1/tcp/0")
    else:
        listen_addr = multiaddr.Multiaddr("/ip6/::1/tcp/0")

    server = make_plaintext_host([listen_addr])
    client = make_plaintext_host()

    async with server.run([listen_addr]):
        async with background_trio_service(client.get_network()):
            await trio.sleep(0.1)
            server_addrs = server.get_addrs()
            print("server addrs:", server_addrs)

            target = info_from_p2p_addr(server_addrs[0])
            await client.connect(target)
            print("connected to server over plaintext")


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Minimal libp2p plaintext repro using IPv6 or IPv4."
    )
    parser.add_argument(
        "--ipv4",
        action="store_true",
        help="Use IPv4 (default is IPv6).",
    )
    args = parser.parse_args()

    trio.run(main, args.ipv4)

If I patch around this problem, I hit another error:

failed to upgrade security for peer 12D3KooWAUtLVoYPSPdTjxYpANDeD3MKzECeQvWfhCLP12WqEkvA: failed to negotiate the secure protocol
Expected behavior

To run without errors

Actual behavior

Errors logs are above

Relevant log output
Errors are above
Possible Solution

None yet

Environment
Python version:
3.12.3 (main, Nov  6 2025, 13:44:16) [GCC 13.3.0]

Operating System: Linux-6.14.0-37-generic-x86_64-with-glibc2.39

python -m pip freeze result:
aioquic==1.3.0
annotated-types==0.7.0
async-generator==1.10
attrs==25.4.0
base58==2.1.1
blake3==1.0.8
certifi==2025.11.12
cffi==2.0.0
coincurve==21.0.0
cryptography==46.0.3
cytoolz==1.1.0
dnspython==2.8.0
eth-hash==0.7.1
eth-typing==5.2.1
eth-utils==5.3.1
fastecdsa==2.3.2
grpcio==1.76.0
h11==0.16.0
idna==3.11
ifaddr==0.2.0
importlib_metadata==8.7.1
libp2p==0.5.0
lru-dict==1.4.1
miniupnpc==2.3.3
mmh3==5.2.0
morphys==1.0
multiaddr==0.0.11
mypy-protobuf==4.0.0
mypy_extensions==1.1.0
netaddr==1.3.0
noiseprotocol==0.3.1
outcome==1.3.0.post0
packaging==25.0
protobuf==6.33.2
psutil==7.2.0
py-cid==0.4.0
py-multibase==2.0.0
py-multicodec==1.0.0
py-multihash==3.0.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.23
pycryptodome==3.23.0
pydantic==2.12.5
pydantic_core==2.41.5
pylsqpack==0.3.23
PyNaCl==1.6.1
pyOpenSSL==25.3.0
python-baseconv==1.2.2
rpcudp==5.0.1
service-identity==24.2.0
six==1.17.0
sniffio==1.3.1
sortedcontainers==2.4.0
toolz==1.1.0
trio==0.32.0
trio-typing==0.10.0
trio-websocket==0.12.2
types-protobuf==6.32.1.20251210
typing-inspection==0.4.2
typing_extensions==4.15.0
u-msgpack-python==2.8.0
varint==1.0.2
wsproto==1.3.2
zeroconf==0.147.3
zipp==3.23.0
Would you like to work on fixing this bug ?

Yes

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at libp2p/transport/tcp/tcp.py line 91 and reproduce the IPv4 and IPv6 cases with the minimal example from the issue. Trace the subsequent security negotiation failure after the IPv6 address lookup is handled; done means the example runs successfully over IPv6 without either reported error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.