Introduction
When Nginx sits behind Cloudflare, the origin sees Cloudflare edge connections by default. If the real_ip module is not configured correctly, access logs, fail2ban rules, geographic controls, and rate limiting all work against Cloudflare IPs instead of the real visitor address.
Symptoms
- Access logs show only Cloudflare edge addresses instead of client IPs
- Rate limiting blocks large groups of unrelated users at once
- Security tools such as fail2ban keep banning Cloudflare IP ranges
- The problem started after putting the site behind Cloudflare or changing proxy settings
Common Causes
- Nginx does not trust Cloudflare proxy IP ranges
- The wrong header is configured for
real_ip_header - Cloudflare IP ranges were configured once but never updated
- Real IP handling is defined in one server block but missing in another
Step-by-Step Fix
- 1.Confirm which IP address Nginx is logging right now
- 2.Check the live access log before changing the configuration so you can verify the fix later.
tail -n 20 /var/log/nginx/access.log- 1.Trust the Cloudflare proxy ranges and use the correct header
- 2.Cloudflare sends the original client address in
CF-Connecting-IP, which Nginx should trust only for Cloudflare proxy ranges.
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
real_ip_header CF-Connecting-IP;
real_ip_recursive on;- 1.Reload Nginx and test with a fresh request
- 2.A config change without a reload leaves the origin serving the old behavior.
nginx -t && systemctl reload nginx
curl -I https://example.com- 1.Verify the logs and security controls now see the visitor IP
- 2.Check logs, geo rules, and rate limiting after the reload so you know downstream controls are using the corrected address.
tail -n 20 /var/log/nginx/access.logPrevention
- Keep Cloudflare IP ranges updated as part of proxy hardening maintenance
- Centralize
real_ipconfiguration in shared Nginx includes - Re-test logging and rate limiting whenever a CDN or reverse proxy changes
- Avoid trusting forwarded IP headers from arbitrary sources
Verification
After applying the fix, verify the exact symptom that made the incident visible instead of relying on one green log line. Re-run the command, request, deployment, or browser path that failed before the change and capture the new output for the incident record.
- Confirm the original error message no longer appears in application, platform, or edge logs.
- Check the affected dependency path from the client side and from the server side when both are available.
- Watch the next scheduled job, deploy, cache refresh, or certificate renewal cycle so the fix survives the normal operating path.
- Record the final configuration value, command output, and timestamp in the runbook for Nginx Real IP Shows Cloudflare Edge IP Instead of the Visitor Address.
Rollback
If the fix changes routing, credentials, certificates, state, cache behavior, or runtime configuration, keep a rollback path ready before applying it to production. Save the previous configuration, identify the owner of the affected service, and define the signal that will trigger rollback.
- 1.Restore the last known-good configuration or state reference if validation shows a wider blast radius.
- 2.Re-run the same diagnostic checks from the fix section to confirm the rollback returned the system to the previous behavior.
- 3.Leave a short note explaining why the attempted fix was reverted so the next responder does not repeat the same change.
Operational Notes
Use this guide as an incident workflow, not as a blind checklist. The safest order is to collect the current state, confirm the narrowest failing component, apply one focused change, and then re-test the same path that failed. Avoid combining unrelated fixes during Nginx Real IP Shows Cloudflare Edge IP Instead of the Visitor Address; otherwise the team will not know which change restored service or which change caused a later regression.
For production systems, capture command output before and after each change. Include timestamps, hostnames, environment names, account IDs, namespaces, certificate names, or configuration keys when they are relevant. These details make the guide useful during a future incident and help separate a real recurrence from a similar-looking but unrelated failure.
Escalate when the failing path crosses a boundary your team does not own, such as a managed cloud control plane, identity provider, external DNS service, payment gateway, or shared network appliance. Share the exact failing request, correlation ID, command output, and change window with the owning team. Keep customer-facing mitigation separate from root-cause repair: it is often safer to route around the broken dependency first, then schedule the permanent cleanup after traffic is stable.
Related Articles
- [Nginx troubleshooting: Fix Lambda Permission Denied - Complete ](fix-lambda-permission-denied)
- [Nginx web server troubleshooting: Fix Client Max Body Size Large Upload Nginx Issue ](client-max-body-size-large-upload-nginx)
- [Fix Apache 502 Proxy Error](fix-apache-502-proxy-error)
- [Fix Apache LogLevel Core Debug Configuration](fix-apache-loglevel-core-debug)
- [Fix Cloudflare 502 Bad Gateway Error](fix-cloudflare-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Nginx Real IP Shows Cloudflare Edge IP Instead of the Visitor Address", "description": "Resolve Nginx real IP issues behind Cloudflare by trusting the correct proxy ranges, using the right header, and validating logs after reload.", "url": "https://www.fixwikihub.com/nginx-real-ip-cloudflare-wrong-client-ip-header", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-10T04:12:00.000Z", "dateModified": "2026-04-10T04:12:00.000Z" } </script>