SonarSource/sonarqube · error · IllegalArgumentException

Maximum number of webhook reached for project

Error message

Maximum number of webhook reached for project '%s'

What it means

Thrown by CreateAction.checkNumberOfWebhook when creating a project-level webhook would push the project to or beyond MAX_NUMBER_OF_WEBHOOKS. SonarQube enforces a hard cap on webhooks per project; the error surfaces as a 400 IllegalArgumentException from the api/webhooks/create endpoint.

Solutions

  1. List existing webhooks with GET api/webhooks/list?project=<key> and delete unneeded ones via api/webhooks/delete.
  2. Reuse/update an existing webhook with api/webhooks/update instead of creating a new one.
  3. Make IaC webhook provisioning idempotent (check existence before create).

Example fix

// before
curl -u $TOKEN -X POST "$SONAR/api/webhooks/create?name=ci&url=$URL&project=$KEY" // fails at cap
// after
EXISTING=$(curl -su $TOKEN "$SONAR/api/webhooks/list?project=$KEY" | jq '.webhooks | length > 0')
if [ "$EXISTING" = "false" ]; then curl -u $TOKEN -X POST "$SONAR/api/webhooks/create?name=ci&url=$URL&project=$KEY"; fi
Defensive patterns

Strategy: validation

Validate before calling

COUNT=$(curl -su "$TOKEN" "$SONAR/api/webhooks/list?project=$KEY" | jq '.webhooks | length')
[ "$COUNT" -lt 10 ] || echo "project webhook cap reached; delete one first"

Try / catch

try {
  createWebhook(...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Maximum number of webhook reached")) {
    deleteOldestWebhook(); createWebhook(...);
  }
}

Prevention

When it happens

Trigger: POST api/webhooks/create with a 'project' parameter when the project already has MAX_NUMBER_OF_WEBHOOKS webhooks configured.

Common situations: Infrastructure-as-code repeatedly creating webhooks (retries or non-idempotent CI config); migrating many integrations onto one project; copying webhook configs from another tool.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/f2b1f55de72bf120. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/webhook/ws/CreateAction.java:169

      checkNumberOfGlobalWebhooks(dbSession);
    }

    return dto;
  }

  private static void writeResponse(Request request, Response response, WebhookDto dto) {
    Webhook.Builder webhookBuilder = Webhook.newBuilder();
    webhookBuilder
      .setKey(dto.getUuid())
      .setName(dto.getName())
      .setUrl(dto.getUrl())
      .setHasSecret(dto.getSecret() != null);
    writeProtobuf(newBuilder().setWebhook(webhookBuilder).build(), request, response);
  }

  private static void checkNumberOfWebhook(int nbOfWebhooks, String projectKey) {
    if (nbOfWebhooks >= MAX_NUMBER_OF_WEBHOOKS) {
      throw new IllegalArgumentException(format("Maximum number of webhook reached for project '%s'", projectKey));
    }
  }

  private int numberOfWebhookOf(DbSession dbSession, ProjectDto projectDto) {
    return dbClient.webhookDao().selectByProject(dbSession, projectDto).size();
  }

  private void checkNumberOfGlobalWebhooks(DbSession dbSession) {
    int globalWebhooksCount = dbClient.webhookDao().selectGlobalWebhooks(dbSession).size();
    if (globalWebhooksCount >= MAX_NUMBER_OF_WEBHOOKS) {
      throw new IllegalArgumentException("Maximum number of global webhooks reached");
    }
  }
}

View on GitHub (pinned to 184c821202)