goto for error handling is not just "freeform anything goes goto". It's a very specific idiom, being an "error" label and a bunch of "if (resource) free(resource)" statements at the end of the function. It is essentially analogous to a common use case of Go's defer. Typically an accepted pattern when dealing with many resources and possible exit points. Prevalent in I/O heavy code.
Different ballgame from the subject of Dijkstra's manifesto.
Really? I have never seen a Go program to misbehave while not printing some meaningful output. It is possible but almost no one ignores the error parameter. Yet I have seen many, many Java and Python software which quit after the first Unhandled Exception. So often that I consider exceptions as the bad error handling mechanism.
It's both common and a good idea, when used purely internally to a function in order to redirect error paths to a standard set of cleanup code. It helps prevents memory errors and other problems.
This is the sense in which the Linux kernel uses goto.
I'm not experienced in C or kernel code but from my understanding they use it almost entirely like a catch/finally clause of many higher level language which is a widely accepted and successful pattern.
Different ballgame from the subject of Dijkstra's manifesto.