The most recent dilemma I faced at work is to decide between returning a 403 (Unauthorised) error as against a 404 (Not Found) error in an API GET call.
The scenario is a resource does not exist on the server, and a user has made a GET call for that resource. The application as part of it’s normal execution, does an authorisation check and reports a 403 error. Now my users are getting confused – have they tried an invalid resource ID or are they having problems with authorisation?

Thinking puristically, we had initially decided to return the errors as is. That is, a 403 would be returned always, even for resources not found on the server. The reasoning was that this benefitted security. It is better to not even let an unauthorised person know whether or not a resource exists. This was an easy decision and doesn’t need much convincing the product mangers. When you say it’s for security, it almost always gets accepted.
But this time around, the decision differed. The same people who had decided 403, now suggested 404. It turns out, the alleviating the users confusion between whether they didn’t have authorisation or whether they’ve made a mistake in the resource ID or whether the dog ate the resource, and so on, was much more important that security.
We went with returning a 404. First the application checks for the resource existence, returns a 404 error if it does not exist. If the resource does exist, we check for authorisation and return 403 error if the user does not have authorisation.
The lesson learnt is that purist attitudes like “correct design” or “security first”, will almost always take a back seat to user experience. Users will not choose your application because it’s architected well or it is secure. Users will choose the application that’s easy for them to use. If you forget this, you will end up with unsatisfied users, who you will not be able to convince that you made decisions for better security or best practice or whatever else.
As a software maker, it’s your responsibility to make software that is first comfortable for your user to use, and then, still ensure that it is secure. So not just for “403 or 404?”, for any such conundrums you face while creating software, remember, customer satisfaction will always beat other factors that may contribute to your decision.
To answer the question “403 or 404?” – Do what your customer will like.