Webhook Troubleshooting Guide
Solutions to common webhook problems and debugging strategies.
Debugging Tools
Dashboard Delivery Attempts
The BlockEden dashboard provides powerful debugging tools:
- Navigate to Accept Payments → Webhooks
 - Click on an endpoint to view its delivery attempts
 - Expand any attempt to see:
Full request body sent by BlockEden Full response body from your server HTTP status code Error messages Response time Retry schedule 
 
Replay Failed Events
Don't worry if a webhook delivery fails - you can replay it:
- Find the failed attempt in the dashboard
 - Click Replay Event button
 - The event will be resent immediately
 - Check if it succeeds this time
 
Test Your Endpoint
Use the Test button to send a sample event:
- Click Test on your endpoint
 - A 
webhook.test.eventis sent with sample data - Verify your server receives and processes it correctly
 - Check server logs and dashboard for results
 
Common Issues
  Issue: "Invalid Signature" (401 Unauthorized)
Symptoms:
- Your endpoint returns HTTP 401
 - Logs show "Invalid signature" or "Unauthorized"
 - All webhook deliveries fail with signature errors
 
Cause 1: Using Parsed JSON Instead of Raw Body
This is the most common mistake. You must verify the signature against the raw request body, not the parsed JSON.
// <ion-icon name="close-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#ef4444"}}></ion-icon> WRONG - Body is already parsed and modified
app.use(express.json());
app.post('/webhooks', (req, res) => {
  const body = JSON.stringify(req.body); // This won't match!
  const signature = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  // Verification will fail
});
// <ion-icon name="checkmark-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#10b981"}}></ion-icon> CORRECT - Use raw body
app.post('/webhooks',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const body = req.body; // Raw Buffer
    const signature = crypto
      .createHmac('sha256', secret)
      .update(body)
      .digest('hex');
    // Verification will succeed
  }
);
Cause 2: Wrong Secret
You may be using an old secret or the wrong endpoint's secret.
Solution:
- Go to dashboard → Click Rotate Secret on your endpoint
 - Copy the new secret immediately (it's only shown once)
 - Update your environment variable: 
WEBHOOK_SECRET=your_new_secret - Restart your server
 - Click Test to verify it works
 
Cause 3: Whitespace or Encoding Issues
Ensure you're using the exact raw bytes without modification.
// Correct approach
const signature = crypto
  .createHmac('sha256', secret)
  .update(req.body) // Must be Buffer, not modified string
  .digest('hex');
  Issue: Webhooks Timing Out
Symptoms:
- Dashboard shows "Timeout" errors
 - No response received after 30 seconds
 - Events are automatically retried
 
Cause 1: Endpoint Takes Too Long to Respond
Your handler is doing too much work synchronously.
// <ion-icon name="close-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#ef4444"}}></ion-icon> WRONG - Slow synchronous processing
app.post('/webhooks', async (req, res) => {
  const event = parseAndVerify(req);
  // This takes 60 seconds - too slow!
  await processOrder(event);
  await sendEmails(event);
  await updateAnalytics(event);
  res.status(200).send('OK'); // Too late - already timed out
});
// <ion-icon name="checkmark-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#10b981"}}></ion-icon> CORRECT - Respond quickly, process async
app.post('/webhooks', async (req, res) => {
  const event = parseAndVerify(req);
  // Respond immediately (within 1 second)
  res.status(200).json({ received: true });
  // Process in background
  processWebhookAsync(event).catch(err => {
    console.error('Background processing error:', err);
    // Log to error tracking service
  });
});
async function processWebhookAsync(event) {
  // Heavy processing here
  await processOrder(event);
  await sendEmails(event);
  await updateAnalytics(event);
}
Cause 2: Endpoint Not Accessible
Your endpoint might be blocked by a firewall, behind a VPN, or using localhost.
Solutions:
Ensure endpoint is publicly accessible over the internet Use HTTPS (HTTP is not supported) Check cloud provider security groups allow inbound HTTPS For local testing, use ngrok: 
# Terminal 1: Start your server
npm start
# Terminal 2: Create secure tunnel
ngrok http 3000
# Output: Forwarding https://abc123.ngrok.io -> http://localhost:3000
# Use the ngrok HTTPS URL in BlockEden dashboard
  Issue: Missing Webhooks
Symptoms:
- Some events aren't received
 - Expected webhook never arrived
 - Inconsistent delivery
 
Cause 1: Not Subscribed to Event Type
You're not subscribed to that specific event type.
Solution:
- Go to dashboard → Edit your endpoint
 - Check the boxes for event types you want to receive
 - Click Save
 
Cause 2: Endpoint Disabled
The endpoint was automatically disabled due to repeated failures.
Solution:
- Check if endpoint shows "Disabled" badge in dashboard
 - Review failure reason in delivery attempts table
 - Fix the underlying issue (signature, timeout, etc.)
 - Click Edit → Toggle "Endpoint active" to re-enable
 - Click Test to verify it works
 
Cause 3: Event Already Sent
BlockEden doesn't send duplicate events - this is correct behavior.
Solution: Each event is sent once per endpoint. Check your server logs or database to confirm if you actually processed it.
  Issue: Duplicate Event Processing
Symptoms:
- Same order fulfilled twice
 - Customer charged multiple times
 - Duplicate database records
 
Cause: Not Implementing Idempotency
Your handler doesn't check if an event was already processed.
// <ion-icon name="close-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#ef4444"}}></ion-icon> WRONG - No duplicate check
async function handleWebhook(event) {
  // Process immediately without checking
  await fulfillOrder(event.data.paymentId);
}
// <ion-icon name="checkmark-circle" style={{verticalAlign: "middle", fontSize: "1.2em", color: "#10b981"}}></ion-icon> CORRECT - Check before processing
async function handleWebhook(event) {
  // Check if already processed using event ID
  const existing = await db.webhookEvents.findOne({
    eventId: event.id
  });
  if (existing) {
    console.log('Event already processed:', event.id);
    return; // Skip duplicate
  }
  // Process the event
  await fulfillOrder(event.data.paymentId);
  // Mark as processed
  await db.webhookEvents.create({
    eventId: event.id,
    type: event.type,
    processedAt: new Date()
  });
}
  Issue: "Connection Refused" Errors
Symptoms:
- Dashboard shows "Connection refused"
 - Error message: "Cannot connect to endpoint"
 - Immediate failure (not timeout)
 
Cause 1: Server Not Running
Your webhook server is down or crashed.
Solution:
Check your server is running: systemctl status your-serviceVerify it's listening on the correct port Check server logs for startup errors Use process manager like PM2 or systemd for auto-restart 
Cause 2: Wrong URL or Port
The webhook URL doesn't match your actual endpoint.
Solution:
Verify URL in dashboard matches your server Check the path: /webhooksvs/webhookvs/api/webhooksEnsure using HTTPS (HTTP not supported) Test with curl: 
curl -X POST https://your-domain.com/api/webhooks \
  -H "Content-Type: application/json" \
  -d '{"test":"data"}'
Cause 3: Firewall Blocking Requests
Corporate firewall or cloud security group is blocking inbound traffic.
Solution:
Allow incoming HTTPS traffic (port 443) Check cloud provider security groups (AWS, GCP, Azure) Verify network ACLs Contact support for BlockEden IP ranges to whitelist