You can abstract over a struct as easily as a pointer, and structs work fine for satisfying interfaces. Specifically, structs make it a little harder for someone to inadvertently mutate things (passed by copy) and because they can’t be nil you don’t need to worry about a non-nil interface implemented by a nil concrete pointer (this is mostly only a problem for people who are new to pointers in my experience). The downside is every time you put a struct into an interface, it gets allocated on the heap, and allocations are expensive in Go (also passing structs can be more expensive than passing pointers).
What I meant about abstraction is that if you define a function which returns an error struct instead of an error interface, you lose any abstraction capability, you can only return that specific struct (and need to find some way of signaling that no error occurred).