GopeedLab/gopeed · error

webhook test failed: %s returned status %d

Error message

webhook test failed: %s returned status %d

What it means

Returned by TestWebhookUrl (webhook.go:187-229) when the endpoint answered but with any status other than exactly HTTP 200. The test posts a simulated DOWNLOAD_DONE payload and treats only StatusOK as success (webhook.go:224-226), so 201, 204, 3xx after redirects, 4xx and 5xx all fail. It verifies end-to-end reachability and receiver acceptance of the JSON body, not just DNS/TCP connectivity (transport failures return the underlying error instead).

Source

Thrown at pkg/download/webhook.go:225

		},
	}

	// Create test data
	testData := &WebhookData{
		Event: WebhookEventDownloadDone,
		Time:  time.Now().UnixMilli(),
		Payload: &WebhookPayload{
			Task: testTask,
		},
	}

	statusCode, err := d.sendWebhookToUrl(url, testData)
	if err != nil {
		return err
	}

	if statusCode != http.StatusOK {
		return fmt.Errorf("webhook test failed: %s returned status %d", url, statusCode)
	}

	return nil
}

View on GitHub (pinned to 7b7327ffb3)

Solutions

  1. Check the receiver's actual response code (curl -i -X POST with a JSON body) and, if it legitimately answers 204 on success, treat the gopeed test failure as a known limitation rather than a broken webhook
  2. Add missing authentication (token header/basic auth) at the receiver or strip it in the proxy in front of it
  3. Ensure the endpoint responds 200 to an application/json POST of a WebhookData-shaped body
  4. Retry the test after transient 5xx clears; verify the URL is the POST endpoint, not a GET page

Example fix

# before
receiver: return 204 No Content on delivery -> gopeed test fails

# after (receiver returns explicit 200)
HTTP/1.1 200 OK
Content-Type: application/json

{"ok":true}
Defensive patterns

Strategy: try-catch

Validate before calling

u, err := neturl.Parse(url)
if err != nil || u.Scheme == "" || u.Host == "" {
	return fmt.Errorf("invalid webhook url %q", url)
}

Try / catch

if err := downloader.TestWebhookUrl(u); err != nil {
	var msg string
	if strings.Contains(err.Error(), "returned status") {
		msg = fmt.Sprintf("receiver rejected test payload: %v (note: endpoints answering 204 fail this test by design)", err)
	} else {
		msg = fmt.Sprintf("webhook unreachable: %v", err)
	}
	return fmt.Errorf("%s", msg)
}

Prevention

When it happens

Trigger: Pointing the test at a receiver that replies 204 No Content (Discord-style acknowledgers), an endpoint requiring authentication (401/403), a gateway returning 502/503 transiently, a URL that redirects to a page returning a non-200, or a receiver that validates the payload and rejects the simulated task with 400.

Common situations: Slack/Discord/Teams-style integrations whose webhooks return 204 on success; reverse proxies or auth layers (Basic auth, API keys, IP allowlists) in front of the receiver; receivers that 400 on the synthetic test task because it references example.com; flaky upstreams during incident windows.

Related errors


AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16). Data as JSON: /api/errors/821e156ed7888e53. Report an issue: GitHub.