Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
Learn a lot again! ++ for "sub-error-codes". From: Everett Toews [mailto:everett.to...@rackspace.com] Sent: Thursday, May 7, 2015 6:26 AM To: OpenStack Development Mailing List (not for usage questions) Subject: Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota On May 6, 2015, at 1:58 PM, David Kranz mailto:dkr...@redhat.com>> wrote: +1 The basic problem is we are trying to fit a square (generic api) peg in a round (HTTP request/response) hole. But if we do say we are recognizing "sub-error-codes", it might be good to actually give them numbers somewhere in the response (maybe an error code header) rather than relying on string matching to determine the real error. String matching is fragile and has icky i18n implications. There is an effort underway around defining such "sub-error-codes" [1]. Those error codes would be surfaced in the REST API here [2]. Naturally feedback is welcome. Everett [1] https://review.openstack.org/#/c/167793/ [2] https://review.openstack.org/#/c/167793/ __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
On May 6, 2015, at 1:58 PM, David Kranz mailto:dkr...@redhat.com>> wrote: +1 The basic problem is we are trying to fit a square (generic api) peg in a round (HTTP request/response) hole. But if we do say we are recognizing "sub-error-codes", it might be good to actually give them numbers somewhere in the response (maybe an error code header) rather than relying on string matching to determine the real error. String matching is fragile and has icky i18n implications. There is an effort underway around defining such "sub-error-codes” [1]. Those error codes would be surfaced in the REST API here [2]. Naturally feedback is welcome. Everett [1] https://review.openstack.org/#/c/167793/ [2] https://review.openstack.org/#/c/167793/ __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
On 05/06/2015 03:15 PM, Chris Dent wrote: > On Wed, 6 May 2015, Jay Pipes wrote: > >> I think Sean makes an excellent point that if you have >1 condition >> that results in a 403 Forbidden, it actually does not make things more >> expressive. It actually just means both humans and clients need to now >> delve deeper into the error context to determine if this is something >> they actually don't have permission to do, or whether they've exceeded >> their quota but otherwise have permission to do some action. > > As I said to Sean in IRC, I can see where you guys are coming from > and I haven't really got a better counter-proposal than "my experience > writing servers and clients doesn't like this" so it's not like I want > to fight about it. I do think it is worth discussion and there are > obviously costs either way that we should identify and balance. > Interestingly, in the process of writing this response I think I've > managed to come up with a few reasons. On the other hand maybe I'm > just getting out yet more paint for the shed. > > Basically it seems to me that the proposal to use 400 just moves the > problem around, one option has conditionals localized under 400, > centralizing the ambiguity. The other option puts the ambiguity in > categories. I guess my brain works better with the latter: a kind of > cascading decision tree. > > Note: I think we're all perpetuating the myth or wish that we actually > do do something in code in response to 400 errors. Maybe in some very > special clients it might happen, but in ad-hoc clients (the best kind) > for the most part we report the status and fail and let the human decide > what's next. Guilty as charged. It may be that the benefit of moving 403->400 isn't worth the trouble in any case (though I'd prefer it) since there are already clients out in the world that may/may not rely on this behavior. > In that sort of context I want the response _codes_ to have some > semantics because I want to branch on the codes (if I branch at all) > and nothing else: > > * 400: bro, something bogus happened, I'm pretty sure it was your >fault > * 401: Tell me who you are and you might get to do this > * 402: You might get to do this if you pay > * 403: You didn't get to do this because the _server_ forbids you > * 404: You didn't get to do this because it ain't there > * 405: You didn't get to do this because that action is not available > * 406: I've got the thing you want, but not in the form you want it > * 407: Some man in the middle proxy needs auth > * 408: You spoke too slowly for my awesome brains > * 409: Somebody else got there first > * 410: Seriously, it ain't there and it never will be > * 411: Why u no content-length!? > * 412: You sent conditional headers and I can't meet their >requirements > * 413: Too big in the body! > * 414: Too big in the URI! > * 415: You sent me a thing and I might have been able to do >something with it if it were in a different form > [...] > > These all mean things as defined by rfcs 7231 and 7235. Those rfcs > were not pulled out of thin air: They are part of the suite of rfcs > that define HTTP. Do we want to do HTTP? Yes, I think so. In that case, > we ought to follow it where possible. > > Each of those codes above have different levels of ambiguity. Some > are quite specific. For example 405, 406, 411, 412 and 415. Where we > can be sure they are the correct response we should use them and > most assuredly _not_ 400. > > 403, as you've both identified, is a lot more squiffy: "the server > understood the request but refuses to authorize it...a request > might be forbidden for reasons unrelated to the credentials". > > Which leads us to 400. How I tend to use 400 is when none of 405, 406, > 409, 411, 412 or 415 can be used because the representation is > _claiming_ legitimate form (based on the headers) and no conditionals > are being violated and where none of 401, 403 or 404 can be used because > the thing is there, I am authentic and the server is not forbidding . > What that means is that there's some crufty about the otherwise good > representation: You've claimed to be sending JSON and you did, but you > left out a required field. > > There is no other 4xx that covers that, thus 400. > > Now if we try to meld my rules with this idea about signifying over > quota, I feel we've now discovered some collisions: > > My use of 400 means "there's something wrong with your request". > This is also what the spec says: "the client seems to have erred". > > Both of these essentially say "that request was pretty okay, but not > quite right and you can change the _request_ (or perhaps the client > side environment) and achieve success". > > In the case of quota you need to change the server side environment, > not this request. In fact if you do change the server (your quota) > and then do the same request again it will likely work. > > Looking at 403 aga
Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
On Wed, 6 May 2015, Jay Pipes wrote: I think Sean makes an excellent point that if you have >1 condition that results in a 403 Forbidden, it actually does not make things more expressive. It actually just means both humans and clients need to now delve deeper into the error context to determine if this is something they actually don't have permission to do, or whether they've exceeded their quota but otherwise have permission to do some action. As I said to Sean in IRC, I can see where you guys are coming from and I haven't really got a better counter-proposal than "my experience writing servers and clients doesn't like this" so it's not like I want to fight about it. I do think it is worth discussion and there are obviously costs either way that we should identify and balance. Interestingly, in the process of writing this response I think I've managed to come up with a few reasons. On the other hand maybe I'm just getting out yet more paint for the shed. Basically it seems to me that the proposal to use 400 just moves the problem around, one option has conditionals localized under 400, centralizing the ambiguity. The other option puts the ambiguity in categories. I guess my brain works better with the latter: a kind of cascading decision tree. Note: I think we're all perpetuating the myth or wish that we actually do do something in code in response to 400 errors. Maybe in some very special clients it might happen, but in ad-hoc clients (the best kind) for the most part we report the status and fail and let the human decide what's next. In that sort of context I want the response _codes_ to have some semantics because I want to branch on the codes (if I branch at all) and nothing else: * 400: bro, something bogus happened, I'm pretty sure it was your fault * 401: Tell me who you are and you might get to do this * 402: You might get to do this if you pay * 403: You didn't get to do this because the _server_ forbids you * 404: You didn't get to do this because it ain't there * 405: You didn't get to do this because that action is not available * 406: I've got the thing you want, but not in the form you want it * 407: Some man in the middle proxy needs auth * 408: You spoke too slowly for my awesome brains * 409: Somebody else got there first * 410: Seriously, it ain't there and it never will be * 411: Why u no content-length!? * 412: You sent conditional headers and I can't meet their requirements * 413: Too big in the body! * 414: Too big in the URI! * 415: You sent me a thing and I might have been able to do something with it if it were in a different form [...] These all mean things as defined by rfcs 7231 and 7235. Those rfcs were not pulled out of thin air: They are part of the suite of rfcs that define HTTP. Do we want to do HTTP? Yes, I think so. In that case, we ought to follow it where possible. Each of those codes above have different levels of ambiguity. Some are quite specific. For example 405, 406, 411, 412 and 415. Where we can be sure they are the correct response we should use them and most assuredly _not_ 400. 403, as you've both identified, is a lot more squiffy: "the server understood the request but refuses to authorize it...a request might be forbidden for reasons unrelated to the credentials". Which leads us to 400. How I tend to use 400 is when none of 405, 406, 409, 411, 412 or 415 can be used because the representation is _claiming_ legitimate form (based on the headers) and no conditionals are being violated and where none of 401, 403 or 404 can be used because the thing is there, I am authentic and the server is not forbidding . What that means is that there's some crufty about the otherwise good representation: You've claimed to be sending JSON and you did, but you left out a required field. There is no other 4xx that covers that, thus 400. Now if we try to meld my rules with this idea about signifying over quota, I feel we've now discovered some collisions: My use of 400 means "there's something wrong with your request". This is also what the spec says: "the client seems to have erred". Both of these essentially say "that request was pretty okay, but not quite right and you can change the _request_ (or perhaps the client side environment) and achieve success". In the case of quota you need to change the server side environment, not this request. In fact if you do change the server (your quota) and then do the same request again it will likely work. Looking at 403 again: "the server understood the request but refuses to authorize it". 4xx means client side error ("The 4xx (Client Error) class of status code indicates that the client seems to have erred."), so arguably over quota doesn't really work in _any_ 4xx because the client made no error, the service just has a quota lower than they need. We don't want to go down the non 4xx road at this time, so given our choices 403 is the one that most sa
Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
On 05/06/2015 02:07 PM, Jay Pipes wrote: Adding [api] topic. API WG members, please do comment. On 05/06/2015 08:01 AM, Sean Dague wrote: On 05/06/2015 07:11 AM, Chris Dent wrote: On Wed, 6 May 2015, Sean Dague wrote: All other client errors, just be a 400. And use the emerging error reporting json to actually tell the client what's going on. Please do not do this. Please use the 4xx codes as best as you possibly can. Yes, they don't always match, but there are several of them for reasons™ and it is usually possible to find one that sort of fits. Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the most part people are talking to OpenStack through "official clients" but a) what happens when they aren't, b) is that the kind of world we want? I certainly don't. I want a world where the HTTP APIs that OpenStack and other services present actually use HTTP and allow a diversity of clients (machine and human). Absolutely. And the problem is there is not enough namespace in the HTTP error codes to accurately reflect the error conditions we hit. So the current model means the following: If you get any error code, it means multiple failure conditions. Throw it away, grep the return string to decide if you can recover. My proposal is to be *extremely* specific for the use of anything besides 400, so there is only 1 situation that causes that to arise. So 403 means a thing, only one thing, ever. Not 2 kinds of things that you need to then figure out what you need to do. If you get a 400, well, that's multiple kinds of errors, and you need to then go conditional. This should provide a better experience for all clients, human and machine. I agree with Sean on this one. Using response codes effectively makes it easier to write client code that is either simple or is able to use generic libraries effectively. Let's be honest: OpenStack doesn't have a great record of using HTTP effectively or correctly. Let's not make it worse. In the case of quota, 403 is fairly reasonable because you are in fact "Forbidden" from doing the thing you want to do. Yes, with the passage of time you may very well not be forbidden so the semantics are not strictly matching but it is more immediately expressive yet not quite as troubling as 409 (which has a more specific meaning). Except it's not, because you are saying to use 403 for 2 issues ("Don't have permissions" and "Out of quota"). Turns out, we have APIs for adjusting quotas, which your user might have access to. So part of 403 space is something you might be able to code yourself around, and part isn't. Which means you should always ignore it and write custom logic client side. Using something beyond 400 is *not* more expressive if it has more than one possible meaning. Then it's just muddy. My point is that all errors besides 400 should have *exactly* one cause, so they are specific. Yes, agreed. I think Sean makes an excellent point that if you have >1 condition that results in a 403 Forbidden, it actually does not make things more expressive. It actually just means both humans and clients need to now delve deeper into the error context to determine if this is something they actually don't have permission to do, or whether they've exceeded their quota but otherwise have permission to do some action. Best, -jay +1 The basic problem is we are trying to fit a square (generic api) peg in a round (HTTP request/response) hole. But if we do say we are recognizing "sub-error-codes", it might be good to actually give them numbers somewhere in the response (maybe an error code header) rather than relying on string matching to determine the real error. String matching is fragile and has icky i18n implications. -David p.s. And, yes, Chris, I definitely do see your side of the coin on this. It's nuanced, and a grey area... __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
Re: [openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
On 05/06/2015 02:07 PM, Jay Pipes wrote: > Adding [api] topic. API WG members, please do comment. > > On 05/06/2015 08:01 AM, Sean Dague wrote: >> On 05/06/2015 07:11 AM, Chris Dent wrote: >>> On Wed, 6 May 2015, Sean Dague wrote: >>> All other client errors, just be a 400. And use the emerging error reporting json to actually tell the client what's going on. >>> >>> Please do not do this. Please use the 4xx codes as best as you >>> possibly can. Yes, they don't always match, but there are several of >>> them for reasons™ and it is usually possible to find one that sort >>> of fits. I agree with Jay here: there are only 100 error codes in the "400" namespace, and (way) more than 100 possible errors. The general 400 is perfectly good as a catch-all where the user can be expected to read the JSON error response for more information, and the other error codes should be used to make it easier for folks to distinguish specific conditions. Let's take the 403 case. If you are denied with your credentials, there's no error handling that you're going to be able to fix that. >>> Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the >>> most part people are talking to OpenStack through "official clients" >>> but a) what happens when they aren't, b) is that the kind of world >>> we want? >>> >>> I certainly don't. I want a world where the HTTP APIs that OpenStack >>> and other services present actually use HTTP and allow a diversity >>> of clients (machine and human). Wanting other clients to be able to "plug right in" is why we try to be RESTful and make error codes that are usable by any client (see the error codes and messages specs). Using "Conflict" and "Forbidden" codes in addition to good error messages will help, if they denote very specific conditions that the user can act on. >> Absolutely. And the problem is there is not enough namespace in the HTTP >> error codes to accurately reflect the error conditions we hit. So the >> current model means the following: >> >> If you get any error code, it means multiple failure conditions. Throw >> it away, grep the return string to decide if you can recover. >> >> My proposal is to be *extremely* specific for the use of anything >> besides 400, so there is only 1 situation that causes that to arise. So >> 403 means a thing, only one thing, ever. Not 2 kinds of things that you >> need to then figure out what you need to do. Agreed >> If you get a 400, well, that's multiple kinds of errors, and you need to >> then go conditional. >> >> This should provide a better experience for all clients, human and >> machine. > > I agree with Sean on this one. > >>> Using response codes effectively makes it easier to write client code >>> that is either simple or is able to use generic libraries effectively. >>> >>> Let's be honest: OpenStack doesn't have a great record of using HTTP >>> effectively or correctly. Let's not make it worse. >>> >>> In the case of quota, 403 is fairly reasonable because you are in >>> fact "Forbidden" from doing the thing you want to do. Yes, with the >>> passage of time you may very well not be forbidden so the semantics >>> are not strictly matching but it is more immediately expressive yet >>> not quite as troubling as 409 (which has a more specific meaning). >> >> Except it's not, because you are saying to use 403 for 2 issues ("Don't >> have permissions" and "Out of quota"). >> >> Turns out, we have APIs for adjusting quotas, which your user might have >> access to. So part of 403 space is something you might be able to code >> yourself around, and part isn't. Which means you should always ignore it >> and write custom logic client side. >> >> Using something beyond 400 is *not* more expressive if it has more than >> one possible meaning. Then it's just muddy. My point is that all errors >> besides 400 should have *exactly* one cause, so they are specific. > > Yes, agreed. > > I think Sean makes an excellent point that if you have >1 condition that > results in a 403 Forbidden, it actually does not make things more > expressive. It actually just means both humans and clients need to now > delve deeper into the error context to determine if this is something > they actually don't have permission to do, or whether they've exceeded > their quota but otherwise have permission to do some action. > > Best, > -jay > > p.s. And, yes, Chris, I definitely do see your side of the coin on this. > It's nuanced, and a grey area... > > __ > OpenStack Development Mailing List (not for usage questions) > Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev -- Ryan Brown / Software Engineer, Openstack / Red Hat, Inc. __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: open
[openstack-dev] [api] Changing 403 Forbidden to 400 Bad Request for OverQuota was: [nova] Which error code should we return when OverQuota
Adding [api] topic. API WG members, please do comment. On 05/06/2015 08:01 AM, Sean Dague wrote: On 05/06/2015 07:11 AM, Chris Dent wrote: On Wed, 6 May 2015, Sean Dague wrote: All other client errors, just be a 400. And use the emerging error reporting json to actually tell the client what's going on. Please do not do this. Please use the 4xx codes as best as you possibly can. Yes, they don't always match, but there are several of them for reasons™ and it is usually possible to find one that sort of fits. Using just 400 is bad for a healthy HTTP ecosystem. Sure, for the most part people are talking to OpenStack through "official clients" but a) what happens when they aren't, b) is that the kind of world we want? I certainly don't. I want a world where the HTTP APIs that OpenStack and other services present actually use HTTP and allow a diversity of clients (machine and human). Absolutely. And the problem is there is not enough namespace in the HTTP error codes to accurately reflect the error conditions we hit. So the current model means the following: If you get any error code, it means multiple failure conditions. Throw it away, grep the return string to decide if you can recover. My proposal is to be *extremely* specific for the use of anything besides 400, so there is only 1 situation that causes that to arise. So 403 means a thing, only one thing, ever. Not 2 kinds of things that you need to then figure out what you need to do. If you get a 400, well, that's multiple kinds of errors, and you need to then go conditional. This should provide a better experience for all clients, human and machine. I agree with Sean on this one. Using response codes effectively makes it easier to write client code that is either simple or is able to use generic libraries effectively. Let's be honest: OpenStack doesn't have a great record of using HTTP effectively or correctly. Let's not make it worse. In the case of quota, 403 is fairly reasonable because you are in fact "Forbidden" from doing the thing you want to do. Yes, with the passage of time you may very well not be forbidden so the semantics are not strictly matching but it is more immediately expressive yet not quite as troubling as 409 (which has a more specific meaning). Except it's not, because you are saying to use 403 for 2 issues ("Don't have permissions" and "Out of quota"). Turns out, we have APIs for adjusting quotas, which your user might have access to. So part of 403 space is something you might be able to code yourself around, and part isn't. Which means you should always ignore it and write custom logic client side. Using something beyond 400 is *not* more expressive if it has more than one possible meaning. Then it's just muddy. My point is that all errors besides 400 should have *exactly* one cause, so they are specific. Yes, agreed. I think Sean makes an excellent point that if you have >1 condition that results in a 403 Forbidden, it actually does not make things more expressive. It actually just means both humans and clients need to now delve deeper into the error context to determine if this is something they actually don't have permission to do, or whether they've exceeded their quota but otherwise have permission to do some action. Best, -jay p.s. And, yes, Chris, I definitely do see your side of the coin on this. It's nuanced, and a grey area... __ OpenStack Development Mailing List (not for usage questions) Unsubscribe: openstack-dev-requ...@lists.openstack.org?subject:unsubscribe http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev