diff --git a/include/opendht/dht_proxy_client.h b/include/opendht/dht_proxy_client.h
index abb0c0882e3fee7908ccab7827b53cc6be8f66e8..7ac306fd56008843911f095997d124fac76befe7 100644
--- a/include/opendht/dht_proxy_client.h
+++ b/include/opendht/dht_proxy_client.h
@@ -263,7 +263,7 @@ private:
      * @return the JSON returned by the proxy
      */
     void getProxyInfos();
-    void onProxyInfos(const Json::Value& val);
+    void onProxyInfos(const Json::Value& val, const sa_family_t& family);
     SockAddr parsePublicAddress(const Json::Value& val);
 
     void opFailed();
@@ -294,7 +294,8 @@ private:
     NodeStatus statusIpv6_ {NodeStatus::Disconnected};
     NodeStats stats4_ {};
     NodeStats stats6_ {};
-    SockAddr publicAddress_;
+    SockAddr publicAddressV4_;
+    SockAddr publicAddressV6_;
 
     InfoHash myid {};
 
diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp
index 757d938153d3cc1b6429153f0580127c1589f1ca..e2dde088e5050d656f585108fd95281c4b5f6a98 100644
--- a/src/dht_proxy_client.cpp
+++ b/src/dht_proxy_client.cpp
@@ -451,39 +451,58 @@ DhtProxyClient::getProxyInfos()
             statusIpv6_ = NodeStatus::Connecting;
     }
 
-    restbed::Uri uri(HTTP_PROTO + serverHost_ + "/");
-    auto req = std::make_shared<restbed::Request>(uri);
+    // A node can have a Ipv4 and a Ipv6. So, we need to retrieve all public ips
+    std::string host, service;
+    auto serviceMarker = serverHost_.find(':');
+    if (serviceMarker != std::string::npos) {
+        host = serverHost_.substr(0, serviceMarker - 1);
+        service = serverHost_.substr(serviceMarker + 1);
+    } else {
+        host = serverHost_;
+    }
+    auto resolved_proxies = SockAddr::resolve(host, service);
+    auto serverHost = serverHost_;
 
     // Try to contact the proxy and set the status to connected when done.
     // will change the connectivity status
-    statusThread_ = std::thread([this, req]{
-        restbed::Http::async(req,
-            [this](const std::shared_ptr<restbed::Request>&,
-                           const std::shared_ptr<restbed::Response>& reply) {
-            auto code = reply->get_status_code();
-            Json::Value proxyInfos;
-            if (code == 200) {
-                restbed::Http::fetch("\n", reply);
-                std::string body;
-                reply->get_body(body);
+    statusThread_ = std::thread([this, resolved_proxies, serverHost]{
+        for (const auto& resolved_proxy: resolved_proxies) {
+            auto server = resolved_proxy.toString();
+            if (resolved_proxy.getFamily() == AF_INET6) {
+                // HACK restbed seems to not correctly handle directly http://[ipv6]
+                // See https://github.com/Corvusoft/restbed/issues/290.
+                server = serverHost;
+            }
+            restbed::Uri uri(HTTP_PROTO + server + "/");
+            auto req = std::make_shared<restbed::Request>(uri);
+            restbed::Http::async(req,
+            [this, resolved_proxy](const std::shared_ptr<restbed::Request>&,
+            const std::shared_ptr<restbed::Response>& reply) {
+                auto code = reply->get_status_code();
+                Json::Value proxyInfos;
+                if (code == 200) {
+                    restbed::Http::fetch("\n", reply);
+                    std::string body;
+                    reply->get_body(body);
 
-                std::string err;
-                Json::CharReaderBuilder rbuilder;
-                auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
-                try {
-                    reader->parse(body.data(), body.data() + body.size(), &proxyInfos, &err);
-                } catch (...) {
+                    std::string err;
+                    Json::CharReaderBuilder rbuilder;
+                    auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader());
+                    try {
+                        reader->parse(body.data(), body.data() + body.size(), &proxyInfos, &err);
+                    } catch (...) {
+                    }
+                    onProxyInfos(proxyInfos, resolved_proxy.getFamily());
                 }
-            }
-            onProxyInfos(proxyInfos);
-            ongoingStatusUpdate_.clear();
-        });
+                ongoingStatusUpdate_.clear();
+            });
+        }
     });
     statusThread_.detach();
 }
 
 void
-DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos)
+DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t& family)
 {
     std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
 
@@ -508,7 +527,10 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos)
         else
             statusIpv6_ = NodeStatus::Disconnected;
 
-        publicAddress_ = parsePublicAddress(proxyInfos["public_ip"]);
+        if (family == AF_INET)
+            publicAddressV4_ = parsePublicAddress(proxyInfos["public_ip"]);
+        else if (family == AF_INET6)
+            publicAddressV6_ = parsePublicAddress(proxyInfos["public_ip"]);
     } catch (...) {}
 
     auto newStatus = std::max(statusIpv4_, statusIpv6_);
@@ -530,9 +552,9 @@ DhtProxyClient::parsePublicAddress(const Json::Value& val)
 {
     auto public_ip = val.asString();
     auto endIp = public_ip.find_last_of(':');
-    std::string service = public_ip.substr(endIp + 1);
-    std::string address = public_ip.substr(0, endIp - 1);
-    auto sa = SockAddr::resolve(address, service);
+    auto marker = (public_ip.size() > 0 && public_ip[0] == '[') ? 1 : 0;
+    std::string address = public_ip.substr(marker, endIp - marker * 2);
+    auto sa = SockAddr::resolve(address);
     if (sa.empty()) return {};
     return sa.front().getMappedIPv4();
 }
@@ -541,8 +563,10 @@ std::vector<SockAddr>
 DhtProxyClient::getPublicAddress(sa_family_t family)
 {
     std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
-    if (not publicAddress_) return {};
-    return publicAddress_.getFamily() == family ? std::vector<SockAddr>{publicAddress_} : std::vector<SockAddr>{};
+    std::vector<SockAddr> result;
+    if (publicAddressV6_ && family != AF_INET) result.emplace_back(publicAddressV6_);
+    if (publicAddressV4_ && family != AF_INET6) result.emplace_back(publicAddressV4_);
+    return result;
 }
 
 size_t