{"record":{"id":"ef1ba5541a45bcc4","repo":"mastra-ai/mastra","slug":"push-notification-failed-with-status-response-st","errorCode":null,"errorMessage":"Push notification failed with status ${response.status} ${response.statusText ?? ''}","messagePattern":"Push notification failed with status (.+?) (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/server/src/server/a2a/push-notification-sender.ts","lineNumber":239,"sourceCode":"          } else if (auth.schemes.includes('Basic')) {\n            headers.set('authorization', `Basic ${auth.credentials}`);\n          }\n        }\n\n        const { requestUrl, hostHeader, servername } = await this.resolveValidatedDestination(\n          config.pushNotificationConfig.url,\n        );\n        const response = await this.postTaskSnapshot({\n          requestUrl,\n          hostHeader,\n          servername,\n          headers,\n          body: JSON.stringify(task),\n          timeout: this.options.timeout ?? 5_000,\n        });\n\n        if (!response.ok) {\n          throw new Error(\n            `Push notification failed with status ${response.status} ${response.statusText ?? ''}`.trim(),\n          );\n        }\n      }),\n    ).then(results => {\n      for (const result of results) {\n        if (result.status === 'rejected') {\n          logger?.error('Failed to deliver A2A push notification', result.reason);\n        }\n      }\n    });\n  }\n}\n","sourceCodeStart":221,"sourceCodeEnd":253,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/a2a/push-notification-sender.ts#L221-L253","documentation":"After fetch succeeds at the transport level, sendNotifications checks response.ok; any non-2xx status from the push notification receiver causes this error containing the HTTP status and statusText. It aggregates delivery failure so task state updates can reflect/skip notification problems.","triggerScenarios":"The registered push endpoint responds 404 (path wrong), 401/403 (auth missing/expired), 500 (receiver bug), 410 (endpoint gone), or 429 (rate limited) when the sender POSTs the task with a 5s default timeout.","commonSituations":"Receiver deployed behind a proxy returning 404 for unknown routes, expired webhook signing credentials, receiver downtime during redeployments, firewalls/CDN blocking the server's egress IP, or the push URL path changing after a receiver refactor.","solutions":["Check the receiver's logs for the corresponding request and its status code","Verify the push notification URL path still matches the receiver's routes","Fix authentication (signatures/tokens) expected by the receiver — 401/403 cases","Inspect whether the receiver returned 5xx due to an internal error and fix that first; then rely on the sender's retry/allSettled aggregation to redeliver"],"exampleFix":"// receiver before\napp.post('/a2a/push-v1', handler) // old route removed -> 404\n// after\napp.post('/a2a/push', handler)","handlingStrategy":"try-catch","validationCode":"// Pre-flight: verify the endpoint answers before registering it\nconst probe = await fetch(pushUrl, { method: 'OPTIONS' });\nif (!probe.ok) throw new Error(`Push endpoint unhealthy: ${probe.status}`);","typeGuard":null,"tryCatchPattern":"try {\n  await sender.sendNotifications(task, configs);\n} catch (err) {\n  const m = err instanceof Error ? /status (\\d+)/.exec(err.message) : null;\n  if (m) {\n    const status = Number(m[1]);\n    if (status === 429 || status >= 500) scheduleRetry(task); // transient\n    else logger.error('Push rejected permanently', { status }); // 4xx: fix config\n  } else throw err;\n}","preventionTips":["Monitor receiver uptime and alert on 5xx spikes","Version your receiver routes and keep old paths alive during migrations","Set realistic timeouts (options.timeout) matching receiver latency","Handle 410 Gone by pruning dead push configs"],"tags":["a2a","http","push-notifications","network"],"backgroundTag":"http-non-2xx-response","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}