SonarSource/sonarqube · error · IllegalArgumentException

Your Gitlab global configuration is incomplete. The GitLab a

Error message

Your Gitlab global configuration is incomplete. The GitLab access token must be set.

What it means

During global GitLab configuration validation, after the URL check, the access token is decrypted and must be present. If the decrypted token is null (none was stored, or it decrypted to null), validation aborts with this IllegalArgumentException because a token is required to verify URL, read and write permissions against GitLab.

Source

Thrown at server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabGlobalSettingsValidator.java:75

  public void validate(AlmSettingDto almSettingDto) {
    String gitlabUrl = almSettingDto.getUrl();
    String accessToken = almSettingDto.getDecryptedPersonalAccessToken(encryption);
    validate(ValidationMode.COMPLETE, gitlabUrl, accessToken);
  }

  public void validate(ValidationMode validationMode, @Nullable String gitlabApiUrl, @Nullable String accessToken) {
    if (gitlabApiUrl == null) {
      throw new IllegalArgumentException("Your Gitlab global configuration is incomplete. The GitLab URL must be set.");
    }
    gitlabApplicationClient.checkUrl(gitlabApiUrl);
    if (ValidationMode.AUTH_ONLY.equals(validationMode)) {
      return;
    }

    String decryptedToken = getDecryptedToken(accessToken);
    if (decryptedToken == null) {
      throw new IllegalArgumentException("Your Gitlab global configuration is incomplete. The GitLab access token must be set.");
    }
    gitlabApplicationClient.checkToken(gitlabApiUrl, decryptedToken);
    gitlabApplicationClient.checkReadPermission(gitlabApiUrl, decryptedToken);
    gitlabApplicationClient.checkWritePermission(gitlabApiUrl, decryptedToken);
  }

  /**
   * Whether the given configuration's token has the {@code api} scope, the only scope that grants the write access
   * the Remediation Agent needs (create branches, open merge requests). Introspects the token directly via
   * {@code GET /personal_access_tokens/self} rather than inferring it from a probe call's side effect: GitLab has
   * reclassified some endpoints (e.g. {@code /markdown}, used by {@link #validate(AlmSettingDto)}) as requiring only
   * {@code read_api}, which made that inference silently pass for a {@code read_api}-only token (SONAR-31861). Kept
   * separate from {@link #validate(AlmSettingDto)}, which must keep succeeding for a {@code read_api}-only token on
   * its existing consumers (PR decoration, validate_binding).
   */
  public boolean hasApiScope(AlmSettingDto almSettingDto) {
    String gitlabUrl = almSettingDto.getUrl();
    if (gitlabUrl == null) {

View on GitHub (pinned to 184c821202)

Solutions

  1. Enter a GitLab personal access token in the global DevOps Platform Integration settings.
  2. If only checking connectivity, use the AUTH_ONLY validation mode which skips token checks.
  3. Verify the token was persisted (alm_settings update call includes personalAccessToken).
  4. Check the encryption/decryption path returns the stored token correctly (encryption key misconfiguration can yield null).

Example fix

// before: COMPLETE validation without token
validator.validate(ValidationMode.COMPLETE, gitlabUrl, null);
// after: either provide the token or use AUTH_ONLY
validator.validate(ValidationMode.AUTH_ONLY, gitlabUrl, null); // skips token checks
Defensive patterns

Strategy: validation

Validate before calling

if (ValidationMode.COMPLETE.equals(mode) &&
    (almSettingDto.getDecryptedPersonalAccessToken(encryption) == null)) {
  throw new IllegalStateException("Store a GitLab personal access token before validating");
}

Type guard

boolean hasToken(AlmSettingDto dto, Encryption encryption) { return dto.getDecryptedPersonalAccessToken(encryption) != null; }

Try / catch

try { validator.validate(validationMode, gitlabUrl, accessToken); } catch (IllegalArgumentException e) { /* ask admin to provide a token, or use AUTH_ONLY */ }

Prevention

When it happens

Trigger: Calling validate(...) with ValidationMode COMPLETE (default) when the ALM setting has no stored personal access token, or the token field is empty/null after decryption — e.g. testing the global config before a token was ever saved.

Common situations: Initial GitLab setup with URL filled but token missing; token cleared from settings; migration/import dropping the encrypted token; using a validation path with a null token while not in AUTH_ONLY mode.

Related errors


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