{"record":{"id":"058b6302a72384f0","repo":"mastra-ai/mastra","slug":"push-notification-url-must-use-http-or-https-ur","errorCode":null,"errorMessage":"Push notification URL must use http or https: ${url.protocol}","messagePattern":"Push notification URL must use http or https: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/server/a2a/push-notification-sender.ts","lineNumber":82,"sourceCode":"    private readonly pushNotificationStore: InMemoryPushNotificationStore,\n    private readonly options: {\n      timeout?: number;\n      tokenHeaderName?: string;\n      fetch?: typeof fetch;\n      lookup?: typeof defaultLookup;\n      allowedHosts?: string[];\n    } = {},\n  ) {}\n\n  getStore() {\n    return this.pushNotificationStore;\n  }\n\n  private async resolveValidatedDestination(rawUrl: string) {\n    const url = new URL(rawUrl);\n\n    if (url.protocol !== 'https:' && url.protocol !== 'http:') {\n      throw new Error(`Push notification URL must use http or https: ${url.protocol}`);\n    }\n\n    const hostname = url.hostname.toLowerCase();\n    if (this.options.allowedHosts && !this.options.allowedHosts.includes(hostname)) {\n      throw new Error(`Push notification host is not allowed: ${hostname}`);\n    }\n\n    if (isDisallowedHostname(hostname)) {\n      throw new Error(`Push notification URL must not target local or internal hosts: ${hostname}`);\n    }\n\n    if (isDisallowedIpAddress(hostname)) {\n      throw new Error(`Push notification URL must not target local or private IPs: ${hostname}`);\n    }\n\n    const resolvedAddresses =\n      isIP(hostname) === 0\n        ? await (this.options.lookup ?? defaultLookup)(hostname, { all: true, verbatim: true })","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/a2a/push-notification-sender.ts#L64-L100","documentation":"The A2A push notification sender validates the destination URL before issuing any HTTP request. If the parsed URL's protocol is not http: or https:, resolveValidatedDestination throws this error to block unsupported schemes (e.g. file:, ftp:, ws:) that fetch may not handle safely.","triggerScenarios":"Registering/updating an A2A task push notification config whose `url` property uses a scheme other than http/https, e.g. 'ftp://example.com/callback', 'ws://...', or a malformed URL that parsed with an unexpected protocol.","commonSituations":"Typos like 'http:/host' or 'http//host', copying an internal callback URL with a custom scheme, misconfigured environment variables holding the push endpoint, or clients sending webhook URLs with protocols the library never supported.","solutions":["Fix the push notification URL to use https:// (or http:// for non-production) scheme","Validate the URL scheme on your side before registering the push notification config","If the value comes from env/config, print the raw value and check for typos or missing slashes","Use HTTPS in production; some deployments reject plain http"],"exampleFix":"// before\nurl: 'ftp://hooks.example.com/a2a/push'\n// after\nurl: 'https://hooks.example.com/a2a/push'","handlingStrategy":"validation","validationCode":"function assertHttpUrl(raw: string) {\n  const u = new URL(raw);\n  if (u.protocol !== 'https:' && u.protocol !== 'http:') {\n    throw new Error(`Push URL must be http(s), got ${u.protocol}`);\n  }\n  return u;\n}","typeGuard":"const isHttpUrl = (raw: string): boolean => {\n  try { const u = new URL(raw); return u.protocol === 'http:' || u.protocol === 'https:'; }\n  catch { return false; }\n};","tryCatchPattern":"try {\n  await sender.sendNotifications(task, configs);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Push notification URL must use http or https')) {\n    logger.warn('Rejecting push config with bad scheme', { err: err.message });\n  } else throw err;\n}","preventionTips":["Always store push endpoints as full https:// URLs","Validate scheme at config-ingestion time, before persisting","Reject non-http(s) schemes in user-supplied webhook inputs"],"tags":["a2a","url-validation","ssrf","push-notifications"],"backgroundTag":"invalid-url-scheme","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}