Skip to content
Latchkey

Slack incoming webhook "no_service" error in CI

Slack returns no_service when it receives a POST to an incoming webhook URL it no longer recognizes. The webhook was deleted, the app was removed from the workspace, or the URL in your secret is wrong. Slack cannot map the request to a channel, so nothing is posted.

What this error means

A build-status notify step posts to the Slack webhook and the response body is the literal string no_service with HTTP 404. The step may still exit 0 if you do not check the body, so notifications silently stop arriving.

Slack response
< HTTP/2 404
no_service

Common causes

The webhook URL was revoked or the app was removed

Incoming webhook URLs are tied to a specific app install. If the app is uninstalled or the webhook is regenerated, the old URL returns no_service for every request.

The secret holds a stale or truncated URL

A SLACK_WEBHOOK_URL secret copied incorrectly, or one that lost its trailing path segment, no longer resolves to a live webhook.

How to fix it

Regenerate the webhook and update the secret

  1. Open the Slack app config, go to Incoming Webhooks, and confirm the webhook still exists for the target channel.
  2. If it was removed, add a new incoming webhook and copy the full URL including the three path segments after /services/.
  3. Update the SLACK_WEBHOOK_URL repository or organization secret with the new value.
Terminal
curl -sS -X POST -H 'Content-type: application/json' \
  --data '{"text":"build passed"}' \
  "$SLACK_WEBHOOK_URL"

Fail the step when Slack does not return ok

Check the HTTP status or body so a broken webhook fails loudly instead of dropping notifications silently.

.github/workflows/ci.yml
- name: Notify Slack
  run: |
    code=$(curl -s -o /tmp/r -w '%{http_code}' -X POST \
      -H 'Content-type: application/json' \
      --data '{"text":"build passed"}' "$SLACK_WEBHOOK_URL")
    [ "$code" = "200" ] || { cat /tmp/r; exit 1; }
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

How to prevent it

  • Store the webhook only in CI secrets and rotate it in one place when it changes.
  • Assert the HTTP status of the notify request so a dead webhook fails the step.
  • Document which Slack app owns the webhook so a reinstall does not orphan it.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →