# 1.9.13 and non\_idempotent

**URL:** <https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377>\
**Category:** NGINX\
**Created:** [March 30, 2016, 3:35am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377 "2016-03-30T03:35:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [March 30, 2016, 3:35am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/1 "2016-03-30T03:35:51Z")

</div>

If I explicitly configured to retry next upstream based on a  
certain http\_xxx, will that stop working if a request is a POST with  
1.9.13? For other http code, I like the idea of not retry if it is non  
idempotent but for one http\_xxx, I want retry no matter what type of  
request.

Thanks  
Frank

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [March 30, 2016, 4:48am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/2 "2016-03-30T04:48:53Z")

</div>

Hello!

On Tue, Mar 29, 2016 at 06:34:59PM -0700, Frank L. wrote:

> If I explicitly configured to retry next upstream based on a  
> certain http\_xxx, will that stop working if a request is a POST with  
> 1.9.13?

Yes. There is no real difference between a network error and an  
HTTP error returned from idempotence point of view. E.g., 502  
error just means that a network error happened somewhere else.

> For other http code, I like the idea of not retry if it is non  
> idempotent but for one http\_xxx, I want retry no matter what type of  
> request.

Just curious - which one?

Note well that if you want finer control of how various HTTP errors are  
handled, you can use proxy\_intercept\_errors with appropriate  
error\_pages configured. See [Module ngx\_http\_proxy\_module](http://nginx.org/r/proxy_intercept_errors).

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [March 30, 2016, 5:04am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/3 "2016-03-30T05:04:48Z")

</div>

It’s a custom error code, think of it as if http\_404, so if the first  
upstream can’t handle this request , it will send “404” saying it is not  
for me, please try next, nginx should then send the same request to next  
upstream.

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [March 30, 2016, 5:27am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/4 "2016-03-30T05:27:00Z")

</div>

Hello!

On Tue, Mar 29, 2016 at 08:04:33PM -0700, Frank L. wrote:

> It’s a custom error code, think of it as if http\_404, so if the first  
> upstream can’t handle this request , it will send “404” saying it is not  
> for me, please try next, nginx should then send the same request to next  
> upstream.

Well, nginx can’t handle custom error codes in  
proxy\_next\_upstream, so this is probably irrelevant anyway.  
Though I was considered excluding http\_403 and http\_404 from  
idempotence checks, it may make sense to do it if there are enough  
such use cases.

> > Yes. There is no real difference between a network error and an  
> > handled, you can use proxy\_intercept\_errors with appropriate
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [April 1, 2016, 4:47am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/5 "2016-04-01T04:47:45Z")

</div>

Does that mean by default if one upstream server is down (connect error  
or  
connect timeout), nginx won’t try the next server and POST request will  
just fail?

Thanks!  
Frank

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [April 1, 2016, 5:32am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/6 "2016-04-01T05:32:09Z")

</div>

Hello!

On Thu, Mar 31, 2016 at 07:46:40PM -0700, Frank L. wrote:

> Does that mean by default if one upstream server is down (connect error or  
> connect timeout), nginx won’t try the next server and POST request will  
> just fail?

No. Quoting CHANGES ([http://nginx.org/en/CHANGES](http://nginx.org/en/CHANGES)):

```
*) Change: non-idempotent requests (POST, LOCK, PATCH) are no longer
   passed to the next server by default if a request has been sent 

```

to a  
backend; the “non\_idempotent” parameter of the  
“proxy\_next\_upstream”  
directive explicitly allows retrying such requests.

Connect errors doesn’t imply that a request has been sent to a  
backend. As long a request hasn’t been sent yet, it can be  
retried to another server without any problems.

See docs here for more details:

> **[non\_idempotent - Module ngx\_http\_proxy\_module](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#non_idempotent)**

–  
Maxim D.

> **[nginx](http://nginx.org/)**

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [April 1, 2016, 5:47pm UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/7 "2016-04-01T17:47:04Z")

</div>

Can you post a quick patch on how to exclude http\_404?

Thanks!  
Frank

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [April 2, 2016, 7:34am UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/8 "2016-04-02T07:34:13Z")

</div>

Will this work?

— ngx\_http\_upstream.c.orig 2016-03-29 15:09:31.000000000 +0000  
+++ ngx\_http\_upstream.c 2016-04-02 05:28:17.877466756 +0000  
@@ -3990,6 +3990,7 @@  
timeout = u-\>conf-\>next\_upstream\_timeout;

```
 if (u->request_sent

```

- 

```
   && (ft_type != NGX_HTTP_UPSTREAM_FT_HTTP_404)
   && (r->method & (NGX_HTTP_POST|NGX_HTTP_LOCK|NGX_HTTP_PATCH)))

```

{  
ft\_type |= NGX\_HTTP\_UPSTREAM\_FT\_NON\_IDEMPOTENT;

---

<div class="post-metadata">

**Author:** ![fjlj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/e79b87/32.png) [@fjlj](https://www.ruby-forum.com/u/fjlj)\
**Post date:** [April 4, 2016, 3:43pm UTC](https://www.ruby-forum.com/t/1-9-13-and-non-idempotent/244377/9 "2016-04-04T15:43:03Z")

</div>

Hello!

On Fri, Apr 01, 2016 at 10:33:22PM -0700, Frank L. wrote:

> ```
> {
> ft_type |= NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT;
> 
> ```

Yes, looks correct.

–  
Maxim D.

> **[nginx](http://nginx.org/)**
