Issue Description
I’m running Stalwart on a server on an internal network with several other services accessible using split DNS, including ntfy, for push notifications.
Stalwart allows registrations but doesn’t send any notifications. As best I can tell, this is because the HTTP client used to send them is hard-coded to OutboundPolicy::PublicOnly, which results in internal IP addresses being discarded, which is problematic because my notification server has an internal IP address.
To confirm, I ran the server with the following patch applied. When I did, push notifications worked correctly.
diff --git a/crates/jmap/src/push/set.rs b/crates/jmap/src/push/set.rs
index c8e7484c..574052c4 100644
--- a/crates/jmap/src/push/set.rs
+++ b/crates/jmap/src/push/set.rs
@@ -425,7 +425,7 @@ fn validate_push_value(
}
fn validate_push_url(url: &str) -> Result<(), OutboundError> {
- OutboundPolicy::PublicOnly.parse_url(url).map(|_| ())
+ OutboundPolicy::Trusted.parse_url(url).map(|_| ())
}
fn parse_email_push(
diff --git a/crates/services/src/state_manager/http.rs b/crates/services/src/state_manager/http.rs
index bb9f5242..1b825932 100644
--- a/crates/services/src/state_manager/http.rs
+++ b/crates/services/src/state_manager/http.rs
@@ -259,7 +259,7 @@ async fn post_object(
pub(crate) fn build_push_client() -> OutboundClient {
OutboundClient::new(
utils::http::http_client_builder(cfg!(stalwart_tests)),
- OutboundPolicy::PublicOnly,
+ OutboundPolicy::Trusted,
Redirects::SameOrganization(MAX_REDIRECTS),
)
}
Expected Behavior
OutboundPolicy::PublicOnly is configurable. When not used, notifications to an internal IP succeed.
Actual Behavior
OutboundPolicy is not configurable. Notifications to an internal IP are blocked.
Reproduction Steps
- Set up ntfy on an internal server with split DNS.
- Register a client for notifications using ntfy
- Trigger something that results in a notification.
Relevant Log Output
2026-10-30T20:55:46Z DEBUG Push subscription error (push-subscription.error) details = "HTTP POST failed", url = "<url>", reason = "error sending request for url (<url>)"
Stalwart Version
v1.x
Installation Method
Docker
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on