How to Fix a 502 Bad Gateway on Ubuntu for Self-Hosted AI Apps

2026-03-24 4 min read ubuntuself-hosted ai

A 502 Bad Gateway error means your reverse proxy received no valid response from the upstream service. In Docker-based AI stacks, a large share of these errors trace back to DNS and service discovery misconfiguration rather than the proxy itself. In self-hosted AI environments, the stack is layered: browser, reverse proxy, app container, inference service, sometimes a database. The proxy is only the messenger.

Start at the proxy. For Nginx:

sudo nginx -t
sudo journalctl -u nginx --since "30 minutes ago"
sudo tail -n 200 /var/log/nginx/error.log

For Caddy:

sudo journalctl -u caddy --since "30 minutes ago"

Look for phrases like connect() failed, connection refused, or upstream timed out. Those phrases tell you whether the proxy cannot reach the app at all or receives malformed responses.

The most common cause is wrong upstream addressing. If your AI app runs in Docker and Nginx runs on the host, proxy_pass http://127.0.0.1:3000; only works if the container publishes port 3000 to the host. If the app lives on an internal Docker network, the host-level proxy cannot reach it directly without a published port.

The second common cause is that the application binds only to localhost inside the container. Many frameworks default to 127.0.0.1. For a proxied deployment, the app usually needs to bind to 0.0.0.0.

Third: startup timing. AI services can take a long time to become ready when loading models. Your proxy comes up instantly and forwards traffic to a service that is not yet ready. The result looks intermittent. Add a proper health check and delay traffic until the app is ready.

Fourth: protocol mismatches. Some inference frontends require websocket upgrade headers. If your proxy sends plain HTTP to the wrong listener, you get 502. Check the upstream documentation rather than reusing a generic proxy snippet.

On Ubuntu, separate host services from containers:

ss -tulpn
docker ps
curl -I http://127.0.0.1:<port>

If curl to the local upstream fails, the reverse proxy is not your main issue. If curl works but the proxy still returns 502, inspect headers, timeout settings, and protocol configuration.

A clean troubleshooting order: validate proxy config syntax, read proxy error logs, confirm the upstream is listening, confirm the app binds to the correct interface, test upstream with curl, verify protocol settings, and adjust timeouts for AI workloads.

The gateway is not bad. It is trying to tell you where the silence begins.

It is useful to separate 502 scenarios into three buckets: no connection, slow connection, and wrong protocol. If the proxy cannot reach the upstream at all, you usually see connection refused or similar errors. If the service is reachable but not ready in time, timeouts appear. If the proxy reaches the wrong kind of listener, or misses required websocket headers, the response often looks malformed or incomplete. Knowing which bucket you are in saves time.

A practical debugging sequence on Ubuntu looks like this:

  1. Confirm the reverse proxy configuration is valid with nginx -t or the Caddy equivalent.
  2. Check recent proxy logs for the exact upstream error string.
  3. Confirm the upstream process or container is actually running.
  4. Test the upstream directly with curl from the same network path the proxy uses.
  5. Verify the app is bound to the correct interface and port.
  6. Review timeouts, websocket headers, and TLS settings if the app is reachable but still failing.

In Docker deployments, networking assumptions cause a large share of 502 errors. If both services run in the same Compose project, it is usually cleaner to proxy to the Docker service name on the internal network. If the proxy runs on the host instead, publish the application port explicitly and test it from the host before blaming the proxy.

Another common issue in AI workloads is cold start time. Model-serving tools can take much longer to become ready than a normal web app. During startup, the container may exist, the port may even appear open, but the actual API is still loading weights or migrations. Health checks and longer upstream timeouts help here, but so does setting expectations: a service that needs forty seconds to become ready should not be treated like one that boots in two.

Also check resource exhaustion. If the app crashes under memory pressure, the reverse proxy only sees a dead upstream. Review container logs, kernel OOM messages, and restart events before assuming the problem is a bad proxy stanza.

Once you adopt this layered approach, 502 debugging becomes much less mystical. You are not fixing a single error page. You are tracing the path between proxy and upstream until the failing assumption becomes visible.

Readers working through adjacent decisions should also look at Reverse Proxy Setup for Self-Hosted AI Services on Ubuntu and Why Your Self-Hosted AI Container Keeps Restarting.

This article is for general information only and should not be treated as professional advice.

Related transmissions
ubuntu
How to Deploy a Simple Blog Agent on Ubuntu with Docker
A practical walkthrough for deploying a basic file-based blog agent workflow on...
local llms
How to Set Up Ollama for Local AI on Linux or macOS
A practical Ollama setup guide covering installation, model pulls, API usage,...
ubuntu
How to Build a Privacy-First AI Workflow on Ubuntu
A practical guide to building a privacy-first AI workflow on Ubuntu using local...
Newsletter

Stay in the signal

Practical guides on self-hosted AI, SEO, and open-source tools — no noise, no spam.

Follow via RSS →

Email signups open soon.