What version of Go are you using (go version)?
$ go version
go version go1.11.5 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/jack/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jack/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build787904603=/tmp/go-build -gno-record-gcc-switches"
What did you do?
- Set a deadline on a TLS connection.
- Do a failing write due to that deadline. As documented the connection is permanently broken.
- Clear deadline (doesn't really matter because connection is permanently broken - but just to mimic what would work for regular TCP connection).
- Do another write.
Demo code: https://github.com/jackc/go-tls-deadline-temporary-error
What did you expect to see?
A net.Error where Temporary() => false or a non-net.Error.
What did you see instead?
An net.Error where Temporary() => true.
This is technically documented behavior After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. But it means that code that works generically with the net.Conn interface cannot rely on temporary errors being (potentially) temporary. It must treat them as permanent.
Perhaps the original failed tls.Conn.Write could return a non-temporary error.
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
Demo code: https://github.com/jackc/go-tls-deadline-temporary-error
What did you expect to see?
A
net.Errorwhere Temporary() => false or a non-net.Error.What did you see instead?
An
net.Errorwhere Temporary() => true.This is technically documented behavior
After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.But it means that code that works generically with thenet.Conninterface cannot rely on temporary errors being (potentially) temporary. It must treat them as permanent.Perhaps the original failed
tls.Conn.Writecould return a non-temporary error.