404 when 403 was expected - is this on purpose?


juste wondering if I did something wrong in my setup, or if the behavior is ‘by design’.

On a small self-hosted instance, let’s say I try to access a project (or a commit or whatever) URL, when authenticated with a user that does not have the rights to view it => I get a 404.

I would have expected a 403.

Can anyone confirm I’m not alone ? :smiley:

Also wondering if it’s something I could change somehow, as it’s really … weird.

Maybe this would help: NGINX settings | GitLab

Should be possible to configure there custom error pages using the example format from the docs, and within the gitlab.rb file.

1 Like

From what I read, I fear I could change the aspect of the error page, but not the http error code itself which is what I’m looking for.

It’s possible yes, you could check to see if an issue exists for such a request: Issues · GitLab.org / GitLab · GitLab failing that you could always open an issue, to see if that functionality can be added for the future. At least, if it is possible, the Gitlab devs should post on the issue when you open it to explain how it can be done, if it is possible.

Either that, or they’ll explain the reasoning behind the way it works right now, and why a 404 appears instead of 403.

I’ve seen this a few times on some other platforms as well (don’t remember anymore where) - and for them it was a security feature. This way it’s harder for potential hacker to understand what’s going on behind the scenes. So for everything that either does not exist or you don’t have access to or whatever, you’ll get 404.

On the other hand, of course for normal people and integration developers, when API gives you 404 you still have no idea is sth wrong with your authentication or request… Been there :sweat_smile:

But I might be wrong and GitLab has another reason to do so, or it is a mistake :smiley:


Agreed, seen this a lot too.

There seems to be two minsets

  • 403 for every case (even when ‘not found’) => you don’t event have the right to know if things exist or not
  • 404 for every case, as you mentioned, you don’t even know if you can try to hack the access

IMHO both are lame approachs, as is ‘hackers’ would be deterred by this :slight_smile:


I digged a bit in gitlab, and apparently there’s absolutely never a 403 thrown, so I bet it’s their approach.

What I managed though is to get back an “old” default error that is still an 404 but says

The page could not be found or you don't have permission to view it.

For the records, I simply added

proxy_intercept_errors on;

in a custom .conf file placed in /etc/gitlab/nginx/conf.d/

and added this in gitlab.rb

nginx['custom_nginx_config'] = "include /etc/gitlab/nginx/conf.d/*.conf;" 

Sort of does the job with minimal hassle.

I could probably have done a custom template too, didn’t want to invest time in this :wink:


It has benefits, because with 404 the “hacker” doesn’t know if there is anything to “hack”, while with 403 “hacker” knows there is something to break.

True, unless you’re on a web resource that sends 403 even when there’s nothing behind, in which case the hacker may want to hack something … for nothing, which one is best security-wise, I don’t know.

(AWS Cloudfront in some situations, for instance)

Anyway, all cases exists, as long as it’s not me doing something wrong in the setup, that’s fine !

thanks all!


As others have mentioned, this is intentional behavior to avoid enumerating resources or leaking information about private objects.

I have found issues going back 6 years that state the same reason.