Chrome automatically retry on timeout of POST request

16,372 views
Skip to first unread message

Vijay Ganta

unread,
Apr 18, 2017, 3:34:16 AM4/18/17
to Chromium-dev
Hello Guys

We are experiencing a strange behavior where the chrome (Version 57.0.2987.133 (64-bit)) is retrying a POST request when there is a timeout. Below are the steps

1) Client submits a POST request to server
2) Server returns 408 after few seconds (Not visible in browser console network tab)
3) The same POST request is submitted to the server by Chrome browser. (Not visible in browser console network tab)
4) The server returns 409 (Duplicate entity) as the previous request was processed successfully. (after the timeout.)

However in the network tab of browser console I can only see one request and after sometime it fails with 409 (Duplicate add of same entity). The 408 response and retry can be seen by using fiddler.

Not sure how to tell chrome not to retry on timeout of POST, PUT, DELETE (possibly using JavaScript) ? Please can anyone help me with this issue at the earliest.

Thanks
Vijay

Takeshi Yoshino

unread,
Apr 18, 2017, 3:44:29 AM4/18/17
to vijq...@gmail.com, net-dev
+net-dev
bcc: chromium-dev

What are you using for sending the request? Form, XHR or fetch()?

Takeshi

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-dev/f5556c44-1f50-48ce-9268-5927416dc360%40chromium.org.

Vijay Ganta

unread,
Apr 18, 2017, 4:08:24 AM4/18/17
to Chromium-dev
Hello Takeshi

I am using XHR for post and not fetch

Regards
Vijay

Takeshi Yoshino

unread,
Apr 18, 2017, 5:03:56 AM4/18/17
to vijq...@gmail.com, Matt Menke, net-dev
Hi Vijay,

Thank you for the answer.

Please reply to this mail so that further conversations get CC-ed to net-dev@ which network stack experts are watching.

For 408 Request Timeout, it looks we have a special logic in HttpNetworkTransaction::DoReadHeadersComplete().


Takeshi

Vijay

--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
    http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.

Vijay Ganta

unread,
Apr 18, 2017, 7:11:06 AM4/18/17
to Chromium-dev, vijq...@gmail.com, mme...@chromium.org, net...@chromium.org
Hello Matt

Should the retry on 408 be done on POST requests as well, as POST is not idempotent?

The retry should only be done to requests of type idempotent and safe, instead of all idempotent? PUT is the case where it is idempotent but unsafe, and if a retry is done on requests of this type, then there a possibility of corrupting the data. 

Please kindly provide a solution by which I can stop Chrome not to retry on requests which are unsafe on 408 irrespective of idempotent or not.

Randy Smith

unread,
Apr 18, 2017, 8:02:57 AM4/18/17
to Vijay Ganta, Chromium-dev, mme...@chromium.org, net...@chromium.org
On Tue, Apr 18, 2017 at 7:11 AM Vijay Ganta <vijq...@gmail.com> wrote:
Hello Matt

Should the retry on 408 be done on POST requests as well, as POST is not idempotent?

My reading of the HTTP spec is that the server in returning the 408 is making a definite "I did not process the request" statement.  The spec says 

"408 Request Timeout
The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time."

(From https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).  Both the fact that it describes the server as giving up on the request (implying it wasn't processed) and the client as specifically allowed to repeat the request (without any reference to the type of request) makes me think that 408 indicates the server didn't process the request.  Thus retry should be safe for non-idempotent requests.  Another argument is that 408 is about the client not producing a request in a given period of time, but if there was enough of a request for the server to process it, that seems incompatible with telling the client that it's done something wrong.

I'd think to read it differently you'd have to think of the server as a non-atomic entity and the timeout occuring within that entity (e.g. the front end timing out while the back end processes).  While I'll agree that many servers are written that way :-}, I think the spec requires them to behave as an atomic entity in many ways, of which this is one.

Could you give a sense as to why you read the spec differently?

-- Randy


 
--
You received this message because you are subscribed to the Google Groups "net-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.
To post to this group, send email to net...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/net-dev/e5fcc2e8-5cc7-4621-ad51-ecfbac48d5df%40chromium.org.

Matt Menke

unread,
Apr 18, 2017, 8:22:53 AM4/18/17
to Randy Smith, Vijay Ganta, Chromium-dev, net-dev
Randy's exactly right.  4xx errors are client errors, not server errors.  i.e., if the server passes the data to some backend system which takes too long to response, that's not a 4xx error.  A 500, 503, or maybe 504 would be appropriate.

To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+unsubscribe@chromium.org.

To post to this group, send email to net...@chromium.org.

Basem Vaseghi

unread,
Jan 11, 2018, 9:22:14 AM1/11/18
to Chromium-dev, rds...@chromium.org, vijq...@gmail.com, net...@chromium.org
As HTTP Codes are being used by most REST based APIs with many different meanings in mind, it would be rather limiting if 1 browser decided to send retries on a specific code. This in turn will force backend developers to either steer away from the given code or work conditionally with it. 
Specially codes in the 500 and 400 range, are widely used in API design to convey errors. Do we need a forced retry in that regard?


To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.

To post to this group, send email to net...@chromium.org.

Matt Menke

unread,
Jan 11, 2018, 9:34:21 AM1/11/18
to Basem Vaseghi, Chromium-dev, Randy Smith, Vijay Ganta, net-dev
Read what a 408 is:

   The 408 (Request Timeout) status code indicates that the server did
   not receive a complete request message within the time that it was
   prepared to wait.  A server SHOULD send the "close" connection option
   (Section 6.1 of [RFC7230]) in the response, since 408 implies that
   the server has decided to close the connection rather than continue
   waiting.  If the client has an outstanding request in transit, the
   client MAY repeat that request on a new connection.

So the server didn't receive a complete request message, and timed out the connection.  This is a pretty clear indication that the server didn't process the request (Since it didn't receive the request), and it's safe to retry.  Servers do have to timeout sockets at some point, and client need to keep around idle sockets for performance reasons, so this is a pretty clear way for a server to indicate that it's timing out one of those sockets (Which we may have reused at the same time the server timed out the socket).

Because there's nothing to prevent server timeout / client reuse races in general, all browsers already retry when this may have happened.  The 408 just gives the server a clear way to indicate that this is actually what happened.

To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+unsubscribe@chromium.org.

To post to this group, send email to net...@chromium.org.
Reply all
Reply to author
Forward
0 new messages