You cannot write a single-threaded program in it (GOMAXPROCS doesn't do what you probably think it does), and the green threading until very recently didn't obey runtime.LockOSThread which meant that you couldn't even guarantee that a function would execute on the same logical thread (which is critical for certain syscalls).
cgo (which is unfortunately necessary if you have C library dependencies) has significant issues like not being able to support union conversion to a Go type -- which means that you have to write helper functions in C and call those to access unions. This is part of a more generic problem that the memory safety model doesn't lend well to systems programming (and unsafe.* is just too scary to be usable everywhere).
Oh, and the syscall package is effectively deprecated and you now have to switch everything to golang.org/x/sys/unix in order to use it properly (though one of the maintainers does nicely send PRs to projects often). This indicates to me that not enough people tested that the "syscall" package interface made sense in the 9 years before 1.0 and the stability guarantee set in (which means that the code which is very important for a systems programming language wasn't widely tested).
If you want to (for instance) use AT_FDCMD with openat(2) you won't be able to because all of the syscall bindings require file descriptors to be a uint -- despite the kernel interface using an int (and the fact that AT_FDCMD is -100 or something like that). Yet they use AT_FDCMD internally -- which means they know it is needed but they elected not to expose this to users.
It uses the "int" type for PIDs instead of using pid_t, for crying out loud. No systems programming language should do that.