diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java
--- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java
+++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpUtil.java
@@ -547,7 +547,11 @@ public static String formatHostnameForHttp(InetSocketAddress addr) {
         if (NetUtil.isValidIpV6Address(hostString)) {
             if (!addr.isUnresolved()) {
                 hostString = NetUtil.toAddressString(addr.getAddress());
+            } else if (hostString.charAt(0) == '[' && hostString.charAt(hostString.length() - 1) == ']') {
+                // If IPv6 address already contains brackets, let's return as is.
+                return hostString;
             }
+
             return '[' + hostString + ']';
         }
         return hostString;

diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpUtilTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpUtilTest.java
--- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpUtilTest.java
+++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpUtilTest.java
@@ -379,6 +379,12 @@ public void testIpv6Unresolved()  {
         assertEquals("[::1]", HttpUtil.formatHostnameForHttp(socketAddress));
     }
 
+    @Test
+    public void testIpv6UnresolvedExplicitAddress()  {
+        InetSocketAddress socketAddress = InetSocketAddress.createUnresolved("[2001:4860:4860:0:0:0:0:8888]", 8080);
+        assertEquals("[2001:4860:4860:0:0:0:0:8888]", HttpUtil.formatHostnameForHttp(socketAddress));
+    }
+
     @Test
     public void testIpv4() throws Exception  {
         InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getByName("10.0.0.1"), 8080);

Malformed ipv6 through proxy
### Expected behavior

The CONNECT request send an well-formed ipv6
CONNECT [2001:0000:130F:0000:0000:09C0:876A:130B]:443
simple bracket

### Actual behavior
The CONNECT request send an malformed ipv6
CONNECT [[2001:0000:130F:0000:0000:09C0:876A:130B]]:443
double bracket

### Steps to reproduce
Sending a https request from an IPV4 network to an IPV6 server through http proxy

### Minimal yet complete reproducer code (or URL to code)
public static String formatHostnameForHttp(InetSocketAddress addr) {
        String hostString = NetUtil.getHostname(addr);
        if (NetUtil.isValidIpV6Address(hostString)) {
            if (!addr.isUnresolved()) {
                hostString = NetUtil.toAddressString(addr.getAddress());
            }

            return '[' + hostString + ']';
        } else {
            return hostString;
        }
    }
When ipv6 is [2001:0000:130F:0000:0000:09C0:876A:130B], the isValidIpV6Address return true, the addr is Unresolved (because the ipv6 is behind the proxy), but brackets is always added and the final result contains double brackets

### Netty version
4.1.107
### JVM version (e.g. `java -version`)
17
### OS version (e.g. `uname -a`)


@dbeau35 we love PRs
org.io.netty.handler.codec.http.HttpUtilTest