{"record":{"id":"89241f15a097e1f8","repo":"Significant-Gravitas/AutoGPT","slug":"webhook-not-configured","errorCode":null,"errorMessage":"Webhook not configured","messagePattern":"Webhook not configured","errorType":"http","errorClass":"HTTPException","httpStatus":503,"severity":"critical","filePath":"autogpt_platform/backend/backend/api/features/v1.py","lineNumber":1426,"sourceCode":"            \"stripe_webhook: dedup release failed for event %s\",\n            event_id,\n            exc_info=True,\n        )\n\n\n@v1_router.post(\n    path=\"/credits/stripe_webhook\", summary=\"Handle Stripe webhooks\", tags=[\"credits\"]\n)\nasync def stripe_webhook(request: Request):\n    webhook_secret = settings.secrets.stripe_webhook_secret\n    if not webhook_secret:\n        # Guard: an empty secret allows HMAC forgery (attacker can compute a valid\n        # signature over the same empty key). Reject all webhook calls when unconfigured.\n        logger.error(\n            \"stripe_webhook: STRIPE_WEBHOOK_SECRET is not configured — \"\n            \"rejecting request to prevent signature bypass\"\n        )\n        raise HTTPException(status_code=503, detail=\"Webhook not configured\")\n\n    # Get the raw request body\n    payload = await request.body()\n    # Get the signature header\n    sig_header = request.headers.get(\"stripe-signature\")\n\n    try:\n        event = stripe.Webhook.construct_event(payload, sig_header, webhook_secret)\n    except ValueError:\n        # Invalid payload\n        raise HTTPException(status_code=400, detail=\"Invalid payload\")\n    except stripe.SignatureVerificationError:\n        # Invalid signature\n        raise HTTPException(status_code=400, detail=\"Invalid signature\")\n\n    # Defensive payload extraction. A malformed payload (missing/non-dict\n    # `data.object`, missing `id`) would otherwise raise KeyError/TypeError\n    # AFTER signature verification — which Stripe interprets as a delivery","sourceCodeStart":1408,"sourceCodeEnd":1444,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/v1.py#L1408-L1444","documentation":"Raised (503) by POST /credits/stripe_webhook when settings.secrets.stripe_webhook_secret is empty. The comment makes the security rationale explicit: with an empty secret, an attacker could compute a valid HMAC signature over the same empty key and forge webhook events (e.g. fake payment completions). All webhook deliveries are therefore rejected until the secret is configured.","triggerScenarios":"Stripe sends a webhook to an environment where STRIPE_WEBHOOK_SECRET is unset/empty — fresh deployments, local dev without the Stripe CLI secret, or a secrets migration that dropped the variable.","commonSituations":"New environment not registered in the Stripe dashboard; developer testing webhooks locally but forgetting to copy the `whsec_...` from `stripe listen`; Helm/K8s secret not mounted; rotated webhook endpoint in Stripe dashboard generating a new secret never propagated to the app.","solutions":["Set STRIPE_WEBHOOK_SECRET to the signing secret of the webhook endpoint (Stripe Dashboard > Developers > Webhooks, or `stripe listen` output for local dev) and restart the backend.","If the endpoint was recreated in Stripe, copy the NEW whsec_... value — secrets change per endpoint.","Confirm the secret actually reaches the process (container env, secret mount) rather than only existing in CI."],"exampleFix":"# before\n# STRIPE_WEBHOOK_SECRET=  (empty)\n\n# after\nSTRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxx","handlingStrategy":"validation","validationCode":"# pre-deploy check\nimport os\nassert os.environ.get('STRIPE_WEBHOOK_SECRET', '').startswith('whsec_'), \\\n    'STRIPE_WEBHOOK_SECRET missing — webhook endpoint will 503'","typeGuard":null,"tryCatchPattern":"Stripe webhook 503 is server-side misconfiguration; callers (Stripe) will retry automatically — monitor delivery failures in the Stripe dashboard rather than catching client-side.","preventionTips":["Add a startup assertion or readiness probe that STRIPE_WEBHOOK_SECRET is set and starts with whsec_.","Automate copying the secret from `stripe listen` into local .env.","When recreating webhook endpoints in Stripe, treat secret rotation as part of the deploy."],"tags":["payments","stripe","webhook","security","configuration","http-503"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}