phacility/phabricator · error · Exception
Buildkite request to target "%s" had the wrong authenticatio
Error message
Buildkite request to target "%s" had the wrong authentication token. The Buildkite pipeline and Harbormaster build step must be configured with the same token.
What it means
Authentication failure for the Buildkite webhook: the X-Buildkite-Token header sent with the delivery is not identical (compared in constant time via phutil_hashes_are_identical) to the 'webhook.token' setting stored on the Buildkite build step. The hook deliberately fails closed so a third party who learns the hook URL cannot forge build.finished events.
Source
Thrown at src/applications/harbormaster/controller/HarbormasterBuildkiteHookController.php:70
'Harbormaster build target "%s" does not exist.',
$target_phid));
}
$step = $target->getBuildStep();
$impl = $step->getStepImplementation();
if (!($impl instanceof HarbormasterBuildkiteBuildStepImplementation)) {
throw new Exception(
pht(
'Harbormaster build target "%s" is not a Buildkite build step. '.
'Only Buildkite steps may be updated via the Buildkite hook.',
$target_phid));
}
$webhook_token = $impl->getSetting('webhook.token');
$request_token = $request->getHTTPHeader('X-Buildkite-Token');
if (!phutil_hashes_are_identical($webhook_token, $request_token)) {
throw new Exception(
pht(
'Buildkite request to target "%s" had the wrong authentication '.
'token. The Buildkite pipeline and Harbormaster build step must '.
'be configured with the same token.',
$target_phid));
}
$state = idx($build, 'state');
switch ($state) {
case 'passed':
$message_type = HarbormasterMessageType::MESSAGE_PASS;
break;
default:
$message_type = HarbormasterMessageType::MESSAGE_FAIL;
break;
}
$api_method = 'harbormaster.sendmessage';View on GitHub (pinned to 5720a38cfe)
Solutions
- Copy the exact webhook.token from the Harbormaster Buildkite step into the Buildkite pipeline's webhook settings (X-Buildkite-Token header), with no extra whitespace.
- If the token may have been pasted with whitespace, set it again cleanly on both sides.
- After updating, re-test with a fresh Buildkite build (old deliveries keep the old header).
- Never leave the step's webhook.token empty; the check will always fail.
Defensive patterns
Strategy: validation
Validate before calling
// Before enabling the hook in Buildkite, verify both sides carry the same token:
$step_token = $impl->getSetting('webhook.token');
assert(strlen($step_token) > 0); // empty token can never authenticate
// then set the identical value as the X-Buildkite-Token header in Buildkite Try / catch
try {
handleBuildkiteDelivery($request);
} catch (Exception $e) {
if (preg_match('/wrong authentication token/', $e->getMessage())) {
// config issue, not transient: alert, do not retry
}
throw $e;
} Prevention
- Store the webhook token in a secret manager and inject it into both Buildkite and the Harbormaster step from one source.
- After any token rotation, update both ends and send a test delivery before resuming real builds.
- Paste tokens with visible whitespace stripped; re-set the setting if a paste may have carried a newline.
When it happens
Trigger: The Buildkite pipeline's webhook notification header/token differs from (or omits) the token saved in the Harbormaster step settings; the token was regenerated in Harbormaster but not updated in Buildkite (or vice versa); trailing whitespace/newline introduced when pasting the token; no token configured on the step at all (null never equals the header).
Common situations: Initial setup where only one side got the token; rotating tokens during a security review and forgetting one side; copying hook URLs between pipelines that use different tokens.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Expected "%s" property to contain a dictionary.
- Harbormaster build target "%s" does not exist.
- Harbormaster build target "%s" is not a Buildkite build step
- Build target ("%s") has the wrong type of build step. Only C
- This object does not support builds with Buildkite.
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/50616c8eef711fd7.
Report an issue: GitHub.