mastra-ai/mastra · error

Push notification failed with status ${response.status} ${re

Error message

Push notification failed with status ${response.status} ${response.statusText ?? ''}

What it means

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.

Source

Thrown at packages/server/src/server/a2a/push-notification-sender.ts:239

          } else if (auth.schemes.includes('Basic')) {
            headers.set('authorization', `Basic ${auth.credentials}`);
          }
        }

        const { requestUrl, hostHeader, servername } = await this.resolveValidatedDestination(
          config.pushNotificationConfig.url,
        );
        const response = await this.postTaskSnapshot({
          requestUrl,
          hostHeader,
          servername,
          headers,
          body: JSON.stringify(task),
          timeout: this.options.timeout ?? 5_000,
        });

        if (!response.ok) {
          throw new Error(
            `Push notification failed with status ${response.status} ${response.statusText ?? ''}`.trim(),
          );
        }
      }),
    ).then(results => {
      for (const result of results) {
        if (result.status === 'rejected') {
          logger?.error('Failed to deliver A2A push notification', result.reason);
        }
      }
    });
  }
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check the receiver's logs for the corresponding request and its status code
  2. Verify the push notification URL path still matches the receiver's routes
  3. Fix authentication (signatures/tokens) expected by the receiver — 401/403 cases
  4. 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

Example fix

// receiver before
app.post('/a2a/push-v1', handler) // old route removed -> 404
// after
app.post('/a2a/push', handler)
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: verify the endpoint answers before registering it
const probe = await fetch(pushUrl, { method: 'OPTIONS' });
if (!probe.ok) throw new Error(`Push endpoint unhealthy: ${probe.status}`);

Try / catch

try {
  await sender.sendNotifications(task, configs);
} catch (err) {
  const m = err instanceof Error ? /status (\d+)/.exec(err.message) : null;
  if (m) {
    const status = Number(m[1]);
    if (status === 429 || status >= 500) scheduleRetry(task); // transient
    else logger.error('Push rejected permanently', { status }); // 4xx: fix config
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/ef1ba5541a45bcc4. Report an issue: GitHub.