SonarSource/sonarqube · error · IllegalArgumentException

For security reasons, the key

Error message

For security reasons, the key '%s' cannot be updated using this webservice. Please use the API v2

What it means

SonarQube's settings web service (api/settings/set) refuses to update a small set of security-sensitive properties whose keys are in FORBIDDEN_KEYS (e.g. sonar.forceAuthentication). These must be managed via the v2 REST API for auditability. throwIfForbiddenKey runs before any persistence in SetAction.handle, so the request is rejected with 400 before the setting is touched.

Solutions

  1. Migrate the call to the API v2 endpoint (e.g. PATCH /api/v2/settings or the dedicated governance endpoint) for that key
  2. Remove the key from automation and set it once via sonar.properties on the server (restart required)
  3. Check the key against FORBIDDEN_KEYS in SetAction.java before calling the API

Example fix

// before
POST /api/settings/set?key=sonar.forceAuthentication&value=true
// after
PATCH /api/v2/governance/... (API v2) or set sonar.forceAuthentication=true in sonar.properties and restart
Defensive patterns

Strategy: validation

Validate before calling

const FORBIDDEN = ['sonar.forceAuthentication'];
if (FORBIDDEN.includes(key)) throw new Error(`Set '${key}' via API v2 or sonar.properties`);

Type guard

function isForbiddenKey(key) { return ['sonar.forceAuthentication'].includes(key); }

Try / catch

try { await setSetting(key, value); } catch (e) { if (/cannot be updated using this webservice/.test(e.message)) return setViaApiV2(key, value); throw e; }

Prevention

When it happens

Trigger: Calling POST api/settings/set with key= one of the FORBIDDEN_KEYS (e.g. sonar.forceAuthentication) regardless of parameters or permissions.

Common situations: Legacy automation scripts, Terraform/Ansible playbooks, or CI jobs written against the old v1 settings API keep setting security properties; environments migrating from older SonarQube versions to ones where these keys were locked down.

Understand the failure class

Background: "is deprecated and will be removed" — deprecation warnings for old API names, keywords, and options, and how to migrate before the removal release — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/setting/ws/SetAction.java:159

    action.createParam(PARAM_COMPONENT)
      .setDescription("Component key. Only keys for projects, applications, portfolios or subportfolios are accepted.")
      .setExampleValue(KEY_PROJECT_EXAMPLE_001);
  }

  @Override
  public void handle(Request request, Response response) throws Exception {
    try (DbSession dbSession = dbClient.openSession(false)) {
      SetRequest wsRequest = toWsRequest(request);
      throwIfForbiddenKey(wsRequest.getKey());
      SettingsWsSupport.validateKey(wsRequest.getKey());
      doHandle(dbSession, wsRequest);
    }
    response.noContent();
  }

  private static void throwIfForbiddenKey(String key) {
    if (FORBIDDEN_KEYS.contains(key)) {
      throw new IllegalArgumentException(format("For security reasons, the key '%s' cannot be updated using this webservice. Please use the API v2", key));
    }
  }

  private void doHandle(DbSession dbSession, SetRequest request) {
    Optional<EntityDto> component = searchEntity(dbSession, request);
    String projectKey = component.map(EntityDto::getKey).orElse(null);
    String projectName = component.map(EntityDto::getName).orElse(null);
    String qualifier = component.map(EntityDto::getQualifier).orElse(null);
    checkPermissions(component);

    PropertyDefinition definition = propertyDefinitions.get(request.getKey());

    String value;

    commonChecks(request, component);

    if (!request.getFieldValues().isEmpty()) {
      value = doHandlePropertySet(dbSession, request, definition, component);

View on GitHub (pinned to 184c821202)