Significant-Gravitas/AutoGPT · warning · HTTPException
Invalid signature
Error message
Invalid signature
What it means
Raised (400) by /credits/stripe_webhook when stripe.Webhook.construct_event raises SignatureVerificationError: the payload parsed fine, but the stripe-signature header does not contain a valid HMAC-SHA256 signature for the body under the configured webhook secret. This is how Stripe's SDK reports forged or mis-keyed deliveries.
Source
Thrown at autogpt_platform/backend/backend/api/features/v1.py:1440
logger.error(
"stripe_webhook: STRIPE_WEBHOOK_SECRET is not configured — "
"rejecting request to prevent signature bypass"
)
raise HTTPException(status_code=503, detail="Webhook not configured")
# Get the raw request body
payload = await request.body()
# Get the signature header
sig_header = request.headers.get("stripe-signature")
try:
event = stripe.Webhook.construct_event(payload, sig_header, webhook_secret)
except ValueError:
# Invalid payload
raise HTTPException(status_code=400, detail="Invalid payload")
except stripe.SignatureVerificationError:
# Invalid signature
raise HTTPException(status_code=400, detail="Invalid signature")
# Defensive payload extraction. A malformed payload (missing/non-dict
# `data.object`, missing `id`) would otherwise raise KeyError/TypeError
# AFTER signature verification — which Stripe interprets as a delivery
# failure and retries forever, while spamming Sentry with no useful info.
# Acknowledge with 200 and a warning so Stripe stops retrying.
event_id = event.get("id", "")
event_type = event.get("type", "")
# Event-level dedup: short-circuit identical re-deliveries before any
# handler runs. Stripe retries the same event.id on non-2xx responses, and
# not every downstream handler is independently idempotent.
if not await _claim_stripe_event(event_id):
logger.info(
"stripe_webhook: event %s (%s) already processed; skipping",
event_id,
event_type,
)View on GitHub (pinned to 9c8bb5550f)
Solutions
- Verify STRIPE_WEBHOOK_SECRET matches the signing secret of the exact Stripe webhook endpoint delivering the event (test and live secrets differ).
- Ensure nothing between Stripe and the app mutates the body — disable body-modifying transforms on the ingress.
- If testing locally, send events via `stripe listen --forward-to ...` and use the CLI's printed secret.
Defensive patterns
Strategy: validation
Validate before calling
# confirm the secret matches the endpoint before going live import stripe, os ep = stripe.WebhookEndpoint.list(limit=100) assert any(os.environ['STRIPE_WEBHOOK_SECRET'] for _ in [0]) # placeholder; real check: secret comes from the same endpoint config
Try / catch
Persistent SignatureVerificationError on genuine Stripe deliveries = secret mismatch or body mutation; investigate ingress (compression/rewrite) and secret config — do not catch and ignore.
Prevention
- One webhook endpoint URL <-> exactly one signing secret; never share a URL across endpoints with different secrets.
- Disable request-body-modifying features (rewrites, encoding normalizations) on the webhook route.
- Keep test-mode and live-mode secrets separated per environment.
When it happens
Trigger: A request with parseable JSON but a missing/incorrect stripe-signature header: attackers replaying modified events, a legitimate Stripe endpoint whose signing secret differs from STRIPE_WEBHOOK_SECRET on this server (e.g. test-mode events hitting a prod secret), or body bytes altered in transit by a proxy.
Common situations: Multiple webhook endpoints in Stripe sharing one URL but different secrets; secret rotated in Stripe but not in the app; TLS-terminating proxy that rewrites the body (e.g. compression/encoding changes); local dev pointing the Stripe CLI at an env with another env's secret.
Related errors
- Webhook not configured
- Invalid payload
- success_url and cancel_url must match the platform frontend
- url must point at a trusted frontend origin.
- Picker tokens are not available for provider '{provider.valu
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/4876e74bc808ebb9.
Report an issue: GitHub.