Skip to main content

Documentation Index

Fetch the complete documentation index at: https://supahooks.ar27111994.dev/llms.txt

Use this file to discover all available pages before exploring further.

This page covers the most common issues you may encounter when running Webhook Debugger & Logger and explains how to resolve each one. Issues are grouped by area so you can jump to the section that matches your symptom.

Authentication issues

When authKey is configured, all management endpoints and the dashboard require the key. Pass it using one of these methods:
# Bearer token in Authorization header
curl -H "Authorization: Bearer <your-key>" "https://<run-id>.runs.apify.net/logs"

# Query parameter
curl "https://<run-id>.runs.apify.net/logs?key=<your-key>"
The key is case-sensitive. Verify that the value you are sending exactly matches the authKey you configured in the actor input.
When authKey is set, webhook ingest (/webhook/:id) also requires authentication — it is not public. Add the key to your provider’s webhook configuration as a header or query parameter.For providers that support custom headers, set:
Authorization: Bearer <your-key>
For providers that only support query parameters, append ?key=<your-key> to the webhook URL.
/health and /ready are never protected by authKey. These endpoints are intentionally public so orchestrators and load balancers can probe them regardless of your auth configuration.
Your source IP is not in the allowedIps list. Check your egress IP address and add it to the allowlist in your actor input.
{
  "allowedIps": ["203.0.113.10/32", "198.51.100.0/24"]
}
If you are behind NAT or a proxy, the IP seen by the actor may differ from your local IP. Use a service like https://api.ipify.org to confirm your public egress address.

Signature verification failures

Check two things:
  1. Secret mismatchsignatureVerificationSecret must match the signing secret shown in your Stripe dashboard. Stripe signing secrets start with whsec_. Copy and paste the value directly to avoid whitespace errors.
  2. Clock skew — Stripe includes a timestamp in its Stripe-Signature header. If the timestamp is older than the configured tolerance (default: 300 seconds), verification fails. Check that your system clock is accurate and increase tolerance if needed.
{
  "signatureVerification": {
    "provider": "stripe",
    "secret": "whsec_...",
    "tolerance": 300
  }
}
Ensure that signatureVerification.secret exactly matches the secret you entered in the GitHub webhook settings. GitHub uses sha256=<hex> in the X-Hub-Signature-256 header, so the algorithm must be sha256.Double-check for trailing whitespace or newline characters — these are a common source of mismatches when copying secrets from a terminal or text editor.
{
  "signatureVerification": {
    "provider": "github",
    "secret": "your-github-webhook-secret"
  }
}
Slack includes a timestamp in the X-Slack-Request-Timestamp header and rejects requests that are too old, even if the HMAC matches. If your system clock is skewed, Slack’s own servers will send timestamps that fall outside your tolerance window.Steps to diagnose:
  1. Verify your system clock is synchronized (NTP).
  2. Check the tolerance setting — the default is 300 seconds. If your environment has a large clock offset, increase this value.
  3. Confirm signatureVerificationSecret matches the signing secret from your Slack App configuration under Basic Information > App Credentials > Signing Secret.

Payload issues

The request body exceeds maxPayloadSize (default: 10 MB, maximum: 100 MB). You have two options:
  • Increase the limit — raise maxPayloadSize in your actor input up to 104857600 (100 MB).
  • Reduce the payload — strip unnecessary fields or compress the body before sending.
{
  "maxPayloadSize": 52428800
}
Values above 100 MB are clamped to the maximum. If your use case requires larger payloads, consider splitting the payload across multiple requests.
The incoming payload does not match the jsonSchema you configured. To diagnose:
  1. Retrieve the raw payload from /logs/:logId/payload to see exactly what was sent.
  2. Validate the payload against your schema using a tool like the JSON Schema Validator.
  3. Adjust either your schema or the payload structure to align them.
If you want to accept the payload while you investigate, temporarily remove the jsonSchema input via hot-reload.
Two common causes:
  1. enableJSONParsing is false — set it to true in your actor input. When enabled, the actor automatically parses application/json bodies into structured objects.
  2. Missing or incorrect Content-Type header — the actor uses the Content-Type header to decide whether to parse the body. Ensure your sender is setting Content-Type: application/json.
curl -X POST "https://<run-id>.runs.apify.net/webhook/wh_abc123" \
  -H "Content-Type: application/json" \
  -d '{"event":"test"}'

Replay and forwarding issues

The url query parameter is required for every replay request. Add the destination URL to your replay call:
curl -X POST \
  "https://<run-id>.runs.apify.net/replay/<webhookId>/<itemId>?url=https://target.example/webhook"
Make sure the URL is properly percent-encoded if it contains special characters.
The destination URL resolves to a private, loopback, link-local, or cloud metadata IP address. The actor blocks these targets to prevent server-side request forgery.Blocked ranges include 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, 169.254.0.0/16, and the cloud metadata address 169.254.169.254.Use a publicly routable hostname or IP as your replay destination. If you are testing locally, use a tunnel service to expose your local server with a public URL.
Check these in order:
  1. forwardUrl is correct and publicly reachable — confirm the URL responds to POST requests from the public internet.
  2. Circuit breaker — if the destination was unreachable or returning errors, the circuit breaker may have tripped. Wait approximately 30 seconds for it to reset automatically.
  3. maxForwardRetries — the default is 3. If all retries are exhausted without a successful response, the forward attempt is marked as failed.
  4. SSRF protection — forwarding to private or reserved IP ranges is blocked for the same reason as replay (see above).
Enable alerts on error or 5xx to be notified immediately when forwarding fails.

Streaming issues

The actor enforces a maximum of 100 concurrent SSE client connections. When this limit is reached, new connections receive 503 Service Unavailable.To resolve this, close any idle or unused SSE connections. Once the active connection count drops below the limit, new connections will be accepted.
Two common causes:
  1. Auth header missing — if authKey is configured, the stream endpoint requires authentication. Pass the key as a header:
    curl -N -H "Authorization: Bearer <your-key>" \
      "https://<run-id>.runs.apify.net/log-stream"
    
  2. Webhook ID has expired — the stream delivers events for all active webhooks in the run. If all webhooks have expired, no events will arrive. Call GET /info to confirm you have at least one active webhook and check its expiresAt time.

General issues

The webhook ID does not exist or has expired. Common causes:
  • The retentionHours window elapsed and the webhook stopped accepting traffic.
  • The webhook ID was typed incorrectly.
  • The actor was restarted and a new set of webhook IDs was generated.
Call GET /info to see all currently active webhooks and their expiry times. Use one of the returned IDs for your requests.
The /logs endpoint queries DuckDB, which syncs from the Apify Dataset asynchronously. There is typically a short lag between when an event is captured and when it appears in query results.The Apify Dataset is the source of truth. If an event was captured, it exists in the Dataset even before DuckDB reflects it.To check the current sync status, call GET /system/metrics:
curl "https://<run-id>.runs.apify.net/system/metrics"
The response includes sync.lastSyncTime, sync.itemsSynced, and sync.errorCount. If errorCount is rising, there may be a sync issue worth investigating.
The actor is not yet ready to serve traffic. This usually means DuckDB or the webhook state has not finished initializing. Wait a few seconds and retry — the actor is likely still starting up.If the /ready endpoint continues returning 503 after 30 seconds, check the actor logs for initialization errors. Restarting the actor typically resolves transient startup failures.
/health and /ready are never protected by authKey, so you can always probe them directly without authentication.