top of page
download (3).png
Search

A Small Fix for a Big Issue: OpenResty, IPv6, and the 90-Second Timeout Mystery

Updated: Aug 5

Recently, while working on a .NET-based UI application deployed with OpenResty as the HTTPS reverse proxy, I ran into a strange issue:The UI would just hang on loading, and after 90 seconds, it would reload automatically or timeout.

At first glance, there was nothing obviously wrong — the backend was up, OpenResty was running, and everything seemed configured correctly.

But something wasn’t right.

🔍 The Problem

When I checked the browser’s network tab, requests were just stuck in the “loading” state. No error messages. No instant failures.Just... a long wait followed by a timeout.

Looking at the OpenResty logs, I found this line:

upstream timed out (110: Connection timed out) while connecting to upstream, client: 99.89.71.217, server: staging.elliedx.com, request: "POST /lapi/json/reply/RetrieveDaOrders HTTP/1.1", upstream: "http://[::1]:5000/lapi/json/reply/RetrieveDaOrders", host: "staging.elliedx.com"

Wait — what’s http://[::1]:5000 doing there?

That’s IPv6 localhost.

But my application DNS and networking were all using IPv4.

Here’s a screenshot from one of our Hetzner servers showing that both IPv4 and IPv6 were assigned during server creation:

ree

🧠 The Root Cause

Digging deeper, I realized that my upstream configuration in OpenResty was set to use localhost. Here's what I had in:


ree

Now, here's the tricky bit: My server (hosted on Hetzner Cloud) had both IPv4 and IPv6 addresses. So when OpenResty resolved localhost, it could resolve to either 127.0.0.1 (IPv4) or ::1 (IPv6).

In this case, it defaulted to IPv6.

But my .NET app was only listening on 127.0.0.1, not on [::1]. That’s why the requests hung — OpenResty was trying to connect over IPv6 and failing silently until a 90-second timeout occurred.

The Fix

A simple change saved the day.

I edited the upstream configuration and replaced localhost with 127.0.0.1 to force IPv4:

/usr/local/openresty/nginx/common/upstreams.conf (After):

ree

Then, I reloaded OpenResty: systemctl reload openresty.service

And just like that — the UI instantly became responsive.

💡 Takeaway

  •  localhost can resolve to both 127.0.0.1 and ::1.

  • If your app only binds to IPv4 (127.0.0.1), make sure your reverse proxy uses that explicitly.

  • Using cloud providers like Hetzner that support IPv6 can expose these subtle issues.

  • Logs are your best friend when debugging "invisible" issues like long timeouts.

What looked like a huge frontend bug turned out to be a tiny config mistake. A 1-line change that made all the difference.

Thanks for reading! Hope this helps someone avoid hours of head-scratching like I had to.

 
 
 
bottom of page