Compare Go fuzz to a java fuzzer and there are some interesting differences. For example, in the Go fuzzer, it is looking for panics, not errors. An error is okay, it just perhaps isn't interesting. With a Java fuzzer, it is looking for Exceptions, which aren't as clear. If you get an IOException, is that working as intended, or an actual failure? It's much harder to tell. I attribute this not the the fuzzer, but to the language design decisions.

I tried using Go Fuzz on a small parser I wrote, and was surprised that it found a bug. I was quite pleased, but the input was actually valid, my code was just wrong. One shortcoming of Fuzzing is that it doesn't find Type II errors. It can't find invalid inputs that do succeed. For example, if the input to my parser was actually invalid, but the code didn't crash, the fuzzer would happily continue on. I'm glad I fuzzed my code, but no errors found doesn't mean no errors present.

1. Errors can be problems in Go as well if they're swallowed and not handled (for example, writing "os.Chdir("/foo");" will silently cause any errors to be ignored). Note that a Java fuzzer that detects uncaught exceptions would notice a failing chdir() written in this way, while the Go fuzzer would not notice this issue.

2. In Java, it's easy to tell whether, say, an IOException was working as intended or was an actual failure. Just check whether it was caught or not. Granted, that won't handle apps that try to catch wide swathes of exception types, but Go apps can abuse Go's "recover" facility in the same way.

There is a useful linter named `errcheck` for Go which looks for swallowed or shadowed errors [1]. It's included in `gometalinter` [2] (which is worth running as part of the CI checks on any Go codebase).

[1] https://github.com/kisielk/errcheck [2] https://github.com/alecthomas/gometalinter