# asana webhook handshake failed x-hook-secret error

## TL;DR
Asana proves you own the endpoint by sending X-Hook-Secret on creation and requiring it echoed in the response header. Make your handler return HTTP 200 with the X-Hook-Secret response header set to the received value, fast, before any slow processing. Store the secret for later event verification, then re-create the webhook.

```text
asana webhook handshake failed x-hook-secret error
```

## Use this when

- Asana webhook creation fails with a handshake or x-hook-secret error
- The webhook never becomes active in Asana
- Your endpoint logs show the initial POST but Asana reports failure

## Not for this skill when

- Asana events not delivered after successful webhook creation (delivery issue)
- Asana API authentication failures (token problem)
- Signature verification failures on delivered events (use the stored secret)

## Steps

### Step 1: Confirm the handshake request arrives

Check your endpoint logs for Asana's initial POST carrying the X-Hook-Secret request header. Expected: you see the handshake attempt and its timing.

### Step 2: Echo the secret in the response

Respond HTTP 200 with the X-Hook-Secret response header set to the exact received value. Expected: the response carries the mirrored header.

### Step 3: Respond fast

Do the echo synchronously before any database writes or slow logic; queue the rest. Expected: response time is milliseconds, well inside Asana's timeout.

### Step 4: Store the secret

Persist the handshake secret for this webhook to verify subsequent event signatures. Expected: the secret is saved keyed by webhook ID.

### Step 5: Re-create the webhook

Create the Asana webhook again now that the endpoint handshakes correctly. Expected: Asana reports the webhook as active.

## Tool compatibility

Asana webhooks API; webhook endpoints that can set custom response headers; Asana developer app tokens.

## Variant phrasings

### Variant 1

asana webhook handshake failed

### Variant 2

asana x-hook-secret not returned webhook creation

### Variant 3

asana webhook 500 handshake timeout fix

## Why it happens

The handshake exists so Asana never sends your data to an endpoint you do not control: it issues a secret, and only a handler that actually receives the request can echo it back. The failure is almost always in the response path rather than the request path. Frameworks that strip unknown headers, async handlers that acknowledge before reading headers, or middleware that converts the handshake POST into something else all break the echo. Slow handlers are the other classic: the secret is echoed correctly but after Asana's timeout, which counts as a failure. The handshake is a tiny synchronous contract; treat it as one.

## Edge cases / pitfalls

- Some frameworks lowercase or drop custom headers; log the exact headers your handler sees.
- Respond to the handshake even if the rest of your webhook pipeline is down; the handshake is independent.
- Each webhook gets its own secret; do not reuse one webhook's secret to verify another's events.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_sup4Ek8lNERWamy0qK0R0Q
