Azure Firewall was erasing every visitor's address
October 2, 2026
I put my lab's entry point behind Azure Firewall and the application stopped knowing who was calling. Why it happens, the fix that looks right and isn't, and what it costs to get back.

My Azure lab has a single door: the firewall's public address. Everything the cluster needs goes out through it, and everything arriving from the internet comes in through it. I liked that design, because a third party only has to put one address on their allow list.
The day I wired the first application behind that door, I opened the access log to see who was showing up. Every request came from the same private address, one inside the firewall's own subnet. Not one visitor showed up with their real address.
Why it happens
The entry point works through address translation on the firewall: a request hits the public address and the firewall forwards it to an internal load balancer in front of the cluster. What I didn't expect is that the firewall rewrites the source as well as the destination. It always does this for traffic matching a translation rule, so the reply comes back through it and the session holds together.
Microsoft documents it. None of the guides I read before starting treated it as something you'd need to plan for.

My first instinct was to distrust my own configuration, so I turned it into a test. Check nine in the lab sends a request from the internet, reads the ingress log and requires the recorded source to be an address in the firewall's subnet. If Azure ever changes this behavior, that check fails and I'll know.
The fix that looks right
Anyone who's worked with Kubernetes knows the setting that keeps the client's address through a load balancer, externalTrafficPolicy set to Local, and the ingress manifest ships with it on. It does nothing here. It keeps the address it receives, and the address it receives is already the firewall's. The information was gone one hop earlier.
I mention it because it's exactly what you'd reach for first, and the first thing you reach for is what wastes the most time when it doesn't work.
What you lose
Without the visitor's address you can't rate-limit per client, you can't apply per-country rules, and the access log is useless for investigating abuse. In a lab I don't care. In an online store or a portal with real users it's a requirement that almost always shows up, and it usually shows up late.
The only way to get it back is to put something further out that reads the address before the firewall and passes it along in a header, an application gateway or a global edge. Each one is another product, with its own price and its own lifecycle.
Coming from Google Cloud, this is what surprised me most. There, an external passthrough network load balancer hands you the client's original address, and an application load balancer passes it along in X-Forwarded-For. On Azure, making the firewall the only way in has this price, and it's worth deciding with that in mind.
The options I weighed
| Option | Cost | Risk | Verdict |
|---|---|---|---|
| Translation on the firewall (what I used) | CostIncluded in the firewall: $0.395 an hour on the Basic tier | RiskThe application never sees the visitor | VerdictFine as long as nobody needs to know who's calling |
| A public load balancer per application | CostOne public address per service, and the trial allows three | RiskInbound traffic leaves the firewall's view | VerdictRejected |
| Application Gateway for Containers | CostIts own subnet and a controller with write access to Azure networking | RiskOne more piece to run and upgrade | VerdictThe next step for production |
| A global edge in front | CostBilled monthly, not prorated | RiskBreaks the habit of tearing the lab down between sessions | VerdictFor production with per-country rules |
I kept translation on the firewall because the lab runs on a trial account that allows three public addresses, and the firewall already uses two: one for traffic and one for the management plane the Basic tier requires. A public load balancer per application didn't fit, and it would have taken inbound traffic out of the firewall's view anyway.
I ruled out the global edge over a cost that isn't on the price sheet. It bills monthly and doesn't prorate, and my lab gets torn down at the end of every session so I'm not paying for firewall hours I don't use.
What I do differently now
When a proposal mentions per-country rules, per-client limits or visitor traceability, I know translation on the firewall won't do as the entry point, and the layer 7 piece goes in the budget from day one. Finding out in production means redesigning the entry point with customers already on it.
The full decision, with Microsoft's references, is in the lab's repository as decision twelve.
One question I'd ask of any architecture with a firewall at the door: which of your customer's requirements depend on knowing who's calling, and at which hop in your network does that information disappear?