mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-02 22:57:34 -05:00
Preserve and Forward X-Forwarded-For Header in Outgoing Requests to *arr #9231
Labels
No labels
Area: API
Area: Database
Area: Db-migration
Area: Download Clients
Area: Extras
Area: Import Lists
Area: Indexer
Area: Metadata API
Area: Notifications
Area: Organizer
Area: Parser
Area: Scanning
Area: Tooling
Area: UI
Area: Unit Tests
On Hold: MetadataAPI Blocking
On Hold: MetadataAPI Blocking
Priority: High
Priority: Low
Priority: Medium
Status: Accepted
Status: Cannot Reproduce
Status: Confirmed
Status: Help Wanted
Status: In Progress
Status: Indexer - need invite
Status: Info Needed
Status: Investigating
Status: Logs Needed
Status: Maybe One Day
Status: Needs Triage
Status: On Hold
Status: Ready for Review
Status: Unlikely
Status: Waiting for OP
Status: Won't Fix
Type: Bug
Type: Documentation
Type: Duplicate
Type: Enhancement
Type: External Bug
Type: Feature Request
Type: Regression
Type: Support
Type: Support.
conflict
lidarr-pull
no-conflict
not-pulled
readarr-pull
readarr-pull
sonarr upstream
sonarr-pull
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/Radarr#9231
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Patrick010 on GitHub (Jul 22, 2025).
Is there an existing issue for this?
Is your feature request related to a problem? Please describe
In many proxied environments (e.g. with Caddy or Nginx), Radarr receives the client’s public IP via the X-Forwarded-For header from a trusted reverse proxy or other application, like Jellyseer. This works as expected. Radarr logs and uses the client IP.
However, when Radarr forwards that request downstream to other applications like Jellyfin, it performs a new outbound HTTP request without preserving or forwarding the original X-Forwarded-For header. As a result, Jellyfin only sees the IP address of the Radarr container or internal host.
This breaks IP attribution across the chain; logs, rate limiting, and audit trails lose the original client context. This is especially relevant in setups where multiple services (e.g. Jellyseerr -> Radarr -> Jellyfin) interact and decisions or logs depend on accurate IP tracing.
Why not just add another proxy?
Yes, technically a reverse proxy could be inserted in front of Radarr to re-inject the missing headers, but doing so adds unnecessary complexity. It introduces more containers, more moving parts, and more points of failure, just to simulate a behavior that could and should be handled at the application level.
Radarr already has access to the original request and headers. It is in the perfect position to pass that information downstream without relying on an external proxy to patch the gap.
This isn’t about offloading work to a proxy, it’s about maintaining context as a responsible link in a multi-service chain.
Proposal
Radarr should:
Example how the header could be assembled:
Why?
Suggested config flag
To keep it optional and safe for all environments, this could be gated behind a config option like:
preserve_forwarded_ip: trueShould this for whatever reason already be possible, then disregard this request.
Describe the solution you'd like
Proposal
Radarr should:
Example how the header could be assembled:
Describe alternatives you've considered
A reverse proxy could be inserted in front of Radarr to re-inject the missing headers, but doing so adds unnecessary complexity. It introduces more containers, more moving parts, and more points of failure, just to simulate a behavior that could and should be handled at the application level.
Anything else?
.
@bakerboy448 commented on GitHub (Jul 22, 2025):
What is the usecase for radarr being used as a command and control client for Jellyfin? What request is made directly to radarr that then results in an immediate and direct call to Jellyfin with no intermediate steps?
@Patrick010 commented on GitHub (Jul 22, 2025):
The usecase is in 'Why'; logging of the correct source IP in stead of the Radarr local IP.
Radarr will get the public IP from the system calling it, being either a proxy, or possibly Jellyfin.
It has nothing to do with being a command and control client, it is just sending the requester's IP, like it should. There is no mayor overhaul or changes needed, only determining the incoming X-Forwarded-For IP and adding that to the header of the Jellyfin (or other) API call.
@bakerboy448 commented on GitHub (Jul 22, 2025):
No plans to arbitrarily pass the forwarded header to subsequent commands.
No functionality exists where radarr is getting by a direct api call that is immediately passed through to another application.
Radarr is not a command and control client for sending and monitoring instructions to your media server. It is a media library manager.
Various headers are already handled
github.com/Radarr/Radarr@71e1003358@Patrick010 commented on GitHub (Jul 22, 2025):
Thanks for your flexibility and for thinking along. I honestly don’t get why they can’t just tweak a handful of lines of code to forward the correct X-Forwarded-For IP to downstream systems. Classic OSS “not invented here” mentality.
@mynameisbogdan commented on GitHub (Jul 22, 2025):
Because Radarr is not a proxy nor a load balancer to make use of that header, thus what you desire it's not the intended purpose for a client to pass the header along.
Considering the automation, many requests aren't even executed from a "parent request".
Let's not break how apps are working just because.
@Patrick010 commented on GitHub (Jul 22, 2025):
My requests improves security by forwarding and logging the source IP.
Again, why the resistance agains putting the proper source IP in the API request? It doesnt make it a LB or Proxy. Its the correct way.
I dont ask for big changes, only a header adjustment in API calls.
@RobinDadswell commented on GitHub (Jul 22, 2025):
Hi Patrick, I think you may be missing what's been said here.
Most, if not all, of the requests that Radarr makes to other services such as Jellyfin are not done from the perspective of the user triggering something, but are done via the automation. E.g. when an import happens, 99% of the time this is not done off the back of a user saying "import this file".
Due to this, we are not going to be adding the x-forwarded-for header to downstreams systems as the traffic doesn't originate downstream but in fact simply originates from the Radarr service.
@Patrick010 commented on GitHub (Jul 22, 2025):
Except when it is triggered by something like Jellyseer. I see requests in my Jellyfin log originating from Radarr while i know that these resquests come from Jellyseer.
And even if it IS originating from Radarr itself, then still it should should fwd the IP of the originating system, not its own. Basic security origin tracebility.
@RobinDadswell commented on GitHub (Jul 22, 2025):
Jellyseer is still not the one doing the import, it is purely doing the request in the first place. Radarr then takes over. If you want Jellyseer to pass the IP to radarr then that is something to talk to the Jellyseer team about not us.
As I said, once Radarr gets hold of "monitor this" everything else is handled by Radarr itself and not the originating system in anyway
@mynameisbogdan commented on GitHub (Jul 22, 2025):
Where did you read this?
@Patrick010 commented on GitHub (Jul 22, 2025):
If you dont understand, just say so, nothing wrong with that.
Radarr, or any system for that matter, should report the originating IP, not its own. Has nothing to do with what system is making the call to Radarr. Radarr will communicate with other systems like Jellyfin. The API call to Jellyfin (in this case) should contain the X-Forwarded-For IP where the request originally came from. All that has to be done is look at the originating IP, which it already does, and put that in the API call to the next system.
If you dont care about security enhancements you can ignore it. Others do care, so again, why the resistance?
@RobinDadswell commented on GitHub (Jul 22, 2025):
This is going to be the final thing on the topic. The originating system for 99.9999999% of things that Radarr does is Radarr itself. Just because a request has been put into the system in the first place by a 3rd party tool does not mean that any future updates mean that it's the origin of that specific API call.
@Patrick010 commented on GitHub (Jul 22, 2025):
ISO/IEC 27002:2022 – Clause 5.12 (Event Logging)
It requires logs to:
ISO/IEC 27002:2022 – Clause 5.15 (Logging Monitoring and Review)
ISO/IEC 27001 Annex A Controls (Mapped)
@bakerboy448 commented on GitHub (Jul 22, 2025):
Let's take a hypothetical usecase since you refused to provided any. There is no reasonable use case where this functionality makes sense to add as noted a few times.
There's no relation between bullet 1 and bullet 3 and thus no relevant information to pass along to Jellyfin that jellyseerr added a movie months/weeks/years/days/hours ago.
No plans to pass along arbitrary headers from the add movie - or any - action to downstream Connections. No benefit is provided. No security implications exist and changing this would actually create a security issue and obfuscate that radarr actually made the calls.
@Patrick010 commented on GitHub (Jul 22, 2025):
So much discussion to not send out the source IP. Laughable.