← back to blog

IPv6 only servers and where MTProto stops working

Why IPv6-only hosts keep showing up

Cheap IPv6-only instances are everywhere now. Providers ration IPv4 addresses because there aren’t enough of them left, so the entry-level tier on a lot of clouds is IPv6-only or IPv6-with-a-shared-NAT-gateway. If you’re spinning up a small box to run an MTProto proxy or a bot, that tier looks attractive. It’s cheaper, sometimes free, and the provisioning is instant because there’s no address scarcity to manage.

The problem shows up later, when someone tries to connect and can’t, and the operator has no idea why, because the server is up, the process is running, and the logs show nothing.

What MTProto actually needs from the network

MTProto is Telegram’s application-layer protocol. It rides on top of TCP (and in some client configurations, on UDP for parts of the transport). None of that cares about IPv4 versus IPv6 in principle, the protocol is address-family agnostic. What matters is whether a TCP or UDP socket can actually be opened between the client and whatever it’s trying to reach, whether that’s a Telegram data center directly or a proxy sitting in front of one.

An MTProto proxy is a relay. The client opens a connection to the proxy’s IP and port, the proxy authenticates the obfuscated handshake, and then it opens its own connection outbound to the actual Telegram DC and shuttles bytes both ways. That means there are two network legs, not one: client-to-proxy, and proxy-to-DC. Either leg can be the one that breaks.

Where the IPv6-only host breaks the chain

If your proxy server only has an IPv6 address, the client-to-proxy leg only works if the client also has working IPv6 connectivity all the way out to the internet. A lot of client devices don’t, even in 2026. Some mobile carriers still don’t hand out IPv6 by default, some home routers have it disabled, and plenty of corporate and campus networks are IPv4-only NAT setups with no v6 uplink at all. On top of that, some devices have IPv6 configured at the OS level but it’s non-functional on that particular network, which is worse than no IPv6 at all because nothing tells the app to fall back.

So an IPv6-only proxy silently excludes every client that can’t get out over v6. There’s no error message that says “this proxy needs IPv6,” the connection attempt just times out or hangs, and from the user’s side it looks like the proxy is dead.

The proxy-to-DC leg is a separate question. Telegram’s data centers are reachable over both IPv4 and IPv6 from most networks, but reachability from any specific host depends on that host’s own routing and on whether the hosting provider’s IPv6 transit is actually solid. An IPv6-only VPS from a provider that treats v6 as an afterthought can have worse peering on that leg than it would have had over v4, which shows up as slow handshakes or connections that eventually fail rather than an outright block.

NAT64 and dual-stack are not the same fix

People sometimes reach for NAT64 or a DNS64 resolver as a patch for IPv6-only hosts, thinking it solves the client-facing problem. It doesn’t, because NAT64 translates outbound connections from an IPv6-only host toward IPv4 destinations, which helps the proxy-to-DC leg if the DC side were IPv4-only, which it generally isn’t. It does nothing for an IPv4-only client trying to reach your IPv6-only proxy, because that client has no v6 stack to translate from in the first place. NAT64 fixes outbound reachability for the host that’s missing an address family, not inbound reachability for clients missing one.

The actual fix for the client-facing side is dual-stack: the proxy needs a real IPv4 address in addition to whatever IPv6 it has, so clients on either stack can reach it. There isn’t a way around this if you want the proxy usable by an unknown mix of client networks, which is the normal situation for anything public-facing.

What this looks like in practice

The failure mode is almost always the same. Someone deploys a proxy on an IPv6-only instance because it was free or cheap. It works fine when they test it from their own machine, because their own ISP or mobile carrier happens to support IPv6. They roll it out, and then a chunk of users report the proxy “doesn’t connect” with no further detail, because the Telegram client just shows a generic connection failure. The operator checks the server, sees it’s running, sees no errors, and has no obvious lead because the server-side logs never see the connection attempt at all. The packets never arrived, they died somewhere between an IPv4-only client and a host that has no IPv4 address to receive them on.

This is different from a proxy being blocked or rate-limited, which usually leaves some trace in the logs. An address-family mismatch leaves nothing, because the connection never reaches the application layer.

How to check before you deploy

Before putting a proxy on any host, it’s worth confirming two things separately. First, does the host itself have a public IPv4 address, not just IPv6. A quick check of the instance’s assigned addresses in the provider’s console settles that. Second, if the plan is IPv6-only, is that being paired with a dual-stack front end, whether that’s a load balancer, a reverse proxy on a different host, or a provider-level NAT gateway that maps an IPv4 address to the instance. Without one of those, an IPv6-only box is only reachable by the subset of the internet that has working outbound IPv6, and that subset is not the whole client base, especially once you count in mobile networks and older corporate infrastructure.

It’s also worth testing the proxy-to-DC leg from the actual host after deployment rather than assuming it works because the host has any IPv6 route at all. A host can have an IPv6 address and still have poor or partial routing to specific destinations if the provider’s v6 peering is thin.

The account safety angle

This matters for account safety too, in a roundabout way. When a proxy is unreachable, clients don’t just fail cleanly, some of them retry the connection repeatedly, sometimes cycling through different network paths or falling back to direct connections without a proxy at all. That’s a change in connection pattern for the account behind that client, and connection pattern changes are one of the things that can affect how an account looks to Telegram’s own systems over time. A proxy that works consistently is part of keeping an account’s network behavior boring and predictable, which is the goal. A proxy that half-works because of an address-family mismatch does the opposite.

Bottom line

MTProto itself doesn’t care about IPv4 versus IPv6, but the hosts and networks it runs over absolutely do. An IPv6-only server is fine as a personal experiment on a network that’s known to support v6 end to end, but it’s the wrong choice for anything meant to serve a broad or unknown set of clients. If you’re running or planning to run proxy infrastructure, confirm you have real dual-stack reachability before you put it in front of real users, not after the connection reports start coming in.

If you want a proxy setup that’s already accounted for this, or you’re trying to figure out why an existing one has been flaky, telegramvault.org is where we write up what we’ve learned running managed Telegram hosting and proxy infrastructure.

Get new guides and videos first — join the Telegram channel.

need infra for this today?