Modern languages have a compiler-checked sum type, and protobuf can support these (oneof). You get the good parts of exceptions (being able to cleanly separate error handling from happy-path code, and doing it concisely and readably via do-notation or equivalent) without the bad parts (invisible nonlocal control flow, breaking referential transparency, hard to abstract over).
(You still have the problem of returning a new type of error condition that your client code wasn't expecting, but it's the same problem as returning a new type of successful value that your client code wasn't expecting, and you can solve it in the exact same way).
I'd settle for 1990s tech over 1970s tech any day when it comes to contracts (APIs).
(There are certainly plenty of places stuck on older tech - but I'd think those places won't be interested in adopting something as new as GRPC)
You have no clean way of describing multiple pre-conditions (refusal reasons), or to evolve those over time in existing systems, without assuming that developers will somehow correctly read your API documentation, and manually write the code everywhere to handle all possible exceptions, with no help from your compiler or your language's type system.
This is how to indicate exceptions in the 1970s. The world has moved on since then :-)