mastra-ai/mastra · error
Push notification host is not allowed: ${hostname}
Error message
Push notification host is not allowed: ${hostname} What it means
When the sender is configured with an `allowedHosts` allowlist, any push notification destination whose lowercased hostname is not in that list is rejected. This is a host-based SSRF/egress control; the library throws instead of silently skipping so the config owner notices.
Source
Thrown at packages/server/src/server/a2a/push-notification-sender.ts:87
lookup?: typeof defaultLookup;
allowedHosts?: string[];
} = {},
) {}
getStore() {
return this.pushNotificationStore;
}
private async resolveValidatedDestination(rawUrl: string) {
const url = new URL(rawUrl);
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
throw new Error(`Push notification URL must use http or https: ${url.protocol}`);
}
const hostname = url.hostname.toLowerCase();
if (this.options.allowedHosts && !this.options.allowedHosts.includes(hostname)) {
throw new Error(`Push notification host is not allowed: ${hostname}`);
}
if (isDisallowedHostname(hostname)) {
throw new Error(`Push notification URL must not target local or internal hosts: ${hostname}`);
}
if (isDisallowedIpAddress(hostname)) {
throw new Error(`Push notification URL must not target local or private IPs: ${hostname}`);
}
const resolvedAddresses =
isIP(hostname) === 0
? await (this.options.lookup ?? defaultLookup)(hostname, { all: true, verbatim: true })
: [{ address: hostname, family: isIP(hostname) }];
if (resolvedAddresses.some(result => isDisallowedIpAddress(result.address))) {
throw new Error(`Push notification URL resolved to a local or private IP: ${hostname}`);
}View on GitHub (pinned to 75dd419e61)
Solutions
- Add the destination hostname (exact, lowercase) to the allowedHosts option of the push notification sender
- Verify the URL hostname matches the allowlist entry exactly, including subdomains
- Remove the allowlist (not recommended) if all hosts should be permitted
- If the domain legitimately changed, update both the push config URL and the allowlist together
Example fix
// before
new PushNotificationSender({ allowedHosts: ['hooks.example.com'] })
// url host: hooks.example.net -> rejected
// after
new PushNotificationSender({ allowedHosts: ['hooks.example.com', 'hooks.example.net'] }) Defensive patterns
Strategy: validation
Validate before calling
function assertAllowedHost(raw: string, allowedHosts: string[]) {
const host = new URL(raw).hostname.toLowerCase();
if (!allowedHosts.includes(host)) throw new Error(`Host ${host} not in allowlist`);
} Try / catch
try {
await sender.sendNotifications(task, configs);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Push notification host is not allowed')) {
logger.error('Push host blocked by allowlist', { err: err.message });
} else throw err;
} Prevention
- Keep allowedHosts in sync with your actual webhook domains
- Remember the allowlist is exact-match, not suffix match — list subdomains explicitly
- Compare hostnames lowercased, as the sender does
When it happens
Trigger: A push notification config URL targets a hostname (after URL parsing and lowercasing) not present in `options.allowedHosts`, e.g. allowedHosts ['hooks.example.com'] but URL host is 'hooks.example.net' or 'hooks.example.com.' variants.
Common situations: Allowlist drift after infrastructure changes (new webhook domain), trailing-dot or case-normalization mismatches, subdomains not listed (allowlist is exact-match, not suffix match), or testing against localhost while the allowlist only has production hosts.
Related errors
- Root is not approved for rendered workspace access
- Push notification URL must use http or https: ${url.protocol
- Push notification URL must not target local or internal host
- Push notification URL must not target local or private IPs:
- Push notification URL resolved to a local or private IP: ${h
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/207f84d271ba4a4a.
Report an issue: GitHub.