What version of Go are you using (go version)?
$ go version
go1.21.1 darwin/amd64
Does this issue reproduce with the latest release?
Yes i tried with latest and older releases as well
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
manikishore.s$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/manikishore.s/Library/Caches/go-build'
GOENV='/Users/manikishore.s/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/manikishore.s/go/pkg/mod'
GONOPROXY='github.com/Manikishore-S'
GONOSUMDB='github.com/Manikishore-S'
GOOS='darwin'
GOPATH='/Users/manikishore.s/go'
GOPRIVATE='github.com/Manikishore-S'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.21.1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/q0/chzy5trn5s17x4d7k4mg38qhw1k3zr/T/go-build3453854944=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
Start a crypto/tls-based webserver with mtls connection as show below.
Server.go
package main
import (
"crypto/tls"
"crypto/x509"
"io"
"io/ioutil"
"log"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
// Write "Hello, world!" to the response body
io.WriteString(w, "Hello, world!\n")
}
func main() {
// Set up a /hello resource handler
http.HandleFunc("/hello", helloHandler)
// Create a CA certificate pool and add cert.pem to it
caCert, err := ioutil.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
ok := caCertPool.AppendCertsFromPEM(caCert)
if !ok {
panic("failed to parse root certificate")
}
// Create the TLS Config with the CA pool and enable Client certificate validation
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
ClientCAs: caCertPool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
// Create a Server instance to listen on port 8443 with the TLS config
server := &http.Server{
Addr: ":8443",
TLSConfig: tlsConfig,
}
// Listen to HTTPS connections with the server certificate and wait
log.Fatal(server.ListenAndServeTLS("server-cert.pem", "server-key.pem"))
}
Client.go
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
// Read the key pair to create certificate
cert, err := tls.LoadX509KeyPair("client-cert.pem", "client-key.pem")
if err != nil {
log.Fatal(err)
}
// Create a CA certificate pool and add cert.pem to it
caCert, err := ioutil.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Create a HTTPS client and supply the created CA pool and certificate
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: caCertPool,
Certificates: []tls.Certificate{cert},
},
},
}
// Request /hello via the created HTTPS client over port 8443 via GET
r, err := client.Get("https://localhost:8443/hello")
if err != nil {
log.Fatal(err)
}
// Read the response body
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
// Print the response body to stdout
fmt.Printf("%s\n", body)
}
What did you expect to see?
You may expect to see a client certificate is getting exchanged for client auth verification. but it is not happening and the connection is normal TLS instead of mTLS.
What did you see instead?
A TLS handshake without client certificate verification in mTLS.

I have tried with other option requestClientCertificate etc but none of them worked. seems a bug.
What version of Go are you using (
go version)?$ go version
go1.21.1 darwin/amd64
Does this issue reproduce with the latest release?
Yes i tried with latest and older releases as well
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
Start a crypto/tls-based webserver with mtls connection as show below.
Server.go
Client.go
What did you expect to see?
You may expect to see a client certificate is getting exchanged for client auth verification. but it is not happening and the connection is normal TLS instead of mTLS.
What did you see instead?
A TLS handshake without client certificate verification in mTLS.

I have tried with other option requestClientCertificate etc but none of them worked. seems a bug.