What's Actually Happening

SonarQube analysis completes but quality gate fails. Code quality metrics don't meet the defined quality gate conditions.

The Error You'll See

```bash $ sonar-scanner

ANALYSIS SUCCESSFUL QUALITY GATE FAILED

# In CI pipeline: Error: SonarQube quality gate failed: <conditions not met> ```

Pipeline blocked:

yaml
# GitHub Actions or Jenkins:
- sonar-scanner
// Analysis completes
// Quality gate: FAILED
// Pipeline fails

Conditions not met:

bash
Quality Gate failed:
- Coverage < 80% (actual: 65%)
- New bugs > 0 (actual: 3)
- Code smells > 50 (actual: 78)

Why This Happens

  1. 1.Coverage threshold not met - Code coverage below minimum
  2. 2.New issues found - Bugs, vulnerabilities, or code smells
  3. 3.Quality profile strict - Rules too strict for project
  4. 4.Gate conditions strict - Quality gate thresholds too aggressive
  5. 5.Baseline not set - No previous analysis for comparison
  6. 6.Exclusions wrong - Files not excluded should be

Step 1: Check Quality Gate Conditions

```bash # In SonarQube UI: # Quality Profiles -> Quality Gates

# Check gate conditions: curl -u admin:admin "http://sonarqube:9000/api/qualitygates/show?name=Sonar%20way"

# List all quality gates: curl -u admin:admin "http://sonarqube:9000/api/qualitygates/list"

# Get project's quality gate: curl -u token: "http://sonarqube:9000/api/qualitygates/get_by_project?project=my-project"

# View conditions: curl -u admin:admin "http://sonarqube:9000/api/qualitygates/show?id=1" | jq '.conditions'

# Common conditions: # - Coverage >= 80% # - New bugs = 0 # - New vulnerabilities = 0 # - New code smells < 50 # - Duplicated lines < 5% ```

Step 2: Check Analysis Results

```bash # View analysis report: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project&metricKeys=coverage,bugs,vulnerabilities,code_smells"

# Get specific metrics: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project&metricKeys=coverage" | jq '.component.measures[0].value'

# Check quality gate status: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project&metricKeys=alert_status"

# View issues: curl -u token: "http://sonarqube:9000/api/issues/search?component=my-project"

# Get new issues: curl -u token: "http://sonarqube:9000/api/issues/search?component=my-project&sinceLeakPeriod=true"

# Check coverage details: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project&metricKeys=coverage,line_coverage,branch_coverage"

# View project measures: curl -u token: "http://sonarqube:9000/api/measures/component_tree?component=my-project&metricKeys=coverage,bugs" ```

Step 3: Analyze Coverage Issues

```bash # Check coverage percentage: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project&metricKeys=coverage"

# If coverage < threshold:

# 1. Check which files have low coverage: curl -u token: "http://sonarqube:9000/api/measures/component_tree?component=my-project&metricKeys=coverage&qualifiers=FIL"

# 2. Find uncovered lines: curl -u token: "http://sonarqube:9000/api/measures/component?component=my-project:src/main.js&metricKeys=uncovered_lines"

# 3. Run coverage locally: npm test -- --coverage jest --coverage pytest --cov=src --cov-report=xml

# 4. Check coverage report uploaded: # sonar.coverageReportPaths=coverage/lcov.info # sonar.python.coverage.reportPaths=coverage.xml

# Generate proper coverage report: # For JavaScript: npm run test -- --coverage --coverageReporters=lcov

# For Java: mvn clean test jacoco:report

# For Python: pytest --cov=src --cov-report=xml:coverage.xml ```

Step 4: Fix New Issues

```bash # Find new bugs: curl -u token: "http://sonarqube:9000/api/issues/search?component=my-project&types=BUG&sinceLeakPeriod=true"

# Find new vulnerabilities: curl -u token: "http://sonarqube:9000/api/issues/search?component=my-project&types=VULNERABILITY&sinceLeakPeriod=true"

# Find new code smells: curl -u token: "http://sonarqube:9000/api/issues/search?component=my-project&types=CODE_SMELL&sinceLeakPeriod=true"

# View issue details: curl -u token: "http://sonarqube:9000/api/issues/search?issues=<issue-key>" | jq '.issues[0]'

# Fix issues in code:

# Example: Unused variable (code smell) # Remove unused code

# Example: Cyclomatic complexity too high # Refactor complex methods

# Example: Potential SQL injection (vulnerability) # Use parameterized queries

# Example: Null pointer dereference (bug) # Add null checks

# Mark as won't fix (if acceptable): curl -u admin:admin -X POST "http://sonarqube:9000/api/issues/do_transition?key=<issue-key>&transition=wontfix" ```

Step 5: Adjust Quality Gate

```bash # Relax quality gate conditions:

# Create custom quality gate: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualitygates/create?name=Relaxed%20Gate"

# Add condition (coverage >= 70% instead of 80%): curl -u admin:admin -X POST "http://sonarqube:9000/api/qualitygates/add_condition?gateId=2&metric=coverage&op=LT&error=70"

# Add condition for bugs: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualitygates/add_condition?gateId=2&metric=new_bugs&op=GT&error=0"

# Associate project with gate: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualitygates/select_project?gateId=2&projectId=<project-id>"

# Or via UI: # Project Settings -> Quality Gate -> Select "Relaxed Gate"

# Common relaxed conditions: # - Coverage >= 60% (instead of 80%) # - New bugs < 5 (instead of 0) # - New code smells < 100 (instead of 50) ```

Step 6: Adjust Quality Profile

```bash # Check quality profile: curl -u admin:admin "http://sonarqube:9000/api/qualityprofiles/search?project=my-project"

# View profile rules: curl -u admin:admin "http://sonarqube:9000/api/rules/search?qprofile=<profile-key>"

# Deactivate strict rules: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/deactivate_rule?key=<profile-key>&rule=<rule-key>"

# Create custom profile: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/create?language=java&name=My%20Profile"

# Copy from built-in: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/copy?fromName=Sonar%20way&toName=My%20Profile&language=java"

# Associate project with profile: curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/associate_project?projectKey=my-project&qualityProfile=My%20Profile&language=java"

# Common rules to deactivate: # - squid:S00112 (too many parameters) # - squid:S1143 (try-catch without finally) # - squid:S1192 (string literal duplicates) ```

Step 7: Configure Proper Exclusions

```bash # Exclude generated code: sonar.exclusions=/generated/,/*.generated.js,/dist/,/build/**

# Exclude test files from coverage: sonar.test.exclusions=/test/,/*.test.js,/*.spec.js

# Exclude specific metrics: sonar.issue.ignore.multicriteria=e1 sonar.issue.ignore.multicriteria.e1.resourceKey=/legacy/ sonar.issue.ignore.multicriteria.e1.ruleKey=java:S1234

# In sonar-project.properties: sonar.projectKey=my-project sonar.sources=src/main sonar.tests=src/test sonar.exclusions=/generated/,**/*.md sonar.coverage.exclusions=/config/,/legacy/

# Exclude coverage for specific files: sonar.coverage.exclusions=/dto/,/entity/

# Via API: curl -u admin:admin -X POST "http://sonarqube:9000/api/project_analyses/create_event?project=my-project&category=VERSION&name=1.0.0" ```

Step 8: Set New Code Period

```bash # Set baseline for new code:

# Define new code period: curl -u admin:admin -X POST "http://sonarqube:9000/api/new_code_periods/set?project=my-project&type=VERSION&value=1.0.0"

# Or use previous version: curl -u admin:admin -X POST "http://sonarqube:9000/api/new_code_periods/set?project=my-project&type=PREVIOUS_VERSION"

# Or number of days: curl -u admin:admin -X POST "http://sonarqube:9000/api/new_code_periods/set?project=my-project&type=NUMBER_OF_DAYS&value=30"

# Check new code period: curl -u admin:admin "http://sonarqube:9000/api/new_code_periods/show?project=my-project"

# This defines what "new code" means for quality gate # Only new code is measured against strict conditions ```

Step 9: Run Analysis with Debug

```bash # Run with verbose output: sonar-scanner -Dsonar.verbose=true

# Check scanner logs: cat .scannerwork/sonar-scanner-*.log

# Debug mode: sonar-scanner -X -Dsonar.logLevel=DEBUG

# Check what files analyzed: sonar-scanner -Dsonar.analysis.mode=publish -Dsonar.verbose=true 2>&1 | grep "Analyzing"

# Check coverage report: sonar-scanner -Dsonar.verbose=true 2>&1 | grep -i coverage

# Check quality gate result: sonar-scanner -Dsonar.qualitygate.wait=true

# Wait for quality gate in CI: sonar-scanner \ -Dsonar.qualitygate.wait=true \ -Dsonar.qualitygate.timeout=300

# Exit code reflects quality gate: # 0 = passed # non-zero = failed ```

Step 10: SonarQube Quality Gate Verification Script

```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-sonar-gate.sh #!/bin/bash

PROJECT=${1:-"my-project"} SONAR_URL=${2:-"http://localhost:9000"} SONAR_TOKEN=${3:-""}

echo "=== Quality Gate Status ===" curl -s -u $SONAR_TOKEN: "$SONAR_URL/api/measures/component?component=$PROJECT&metricKeys=alert_status" | jq '.component.measures[0].value'

echo "" echo "=== Coverage ===" curl -s -u $SONAR_TOKEN: "$SONAR_URL/api/measures/component?component=$PROJECT&metricKeys=coverage,line_coverage,branch_coverage" | jq '.component.measures'

echo "" echo "=== Issues Summary ===" curl -s -u $SONAR_TOKEN: "$SONAR_URL/api/measures/component?component=$PROJECT&metricKeys=bugs,vulnerabilities,code_smells" | jq '.component.measures'

echo "" echo "=== New Issues ===" curl -s -u $SONAR_TOKEN: "$SONAR_URL/api/measures/component?component=$PROJECT&metricKeys=new_bugs,new_vulnerabilities,new_code_smells" | jq '.component.measures'

echo "" echo "=== Quality Gate Conditions ===" curl -s -u admin:admin "$SONAR_URL/api/qualitygates/get_by_project?project=$PROJECT" | jq '.qualityGate.conditions'

echo "" echo "=== Quality Profile ===" curl -s -u admin:admin "$SONAR_URL/api/qualityprofiles/search?project=$PROJECT" | jq '.profiles[0].name'

echo "" echo "=== New Code Period ===" curl -s -u admin:admin "$SONAR_URL/api/new_code_periods/show?project=$PROJECT" | jq '.newCodePeriod'

echo "" echo "=== Recommendations ===" echo "1. Check coverage meets threshold (add tests)" echo "2. Fix new bugs and vulnerabilities" echo "3. Review code smells and refactor" echo "4. Adjust quality gate conditions if too strict" echo "5. Configure proper file exclusions" echo "6. Set new code period baseline" echo "7. Deactivate unnecessary rules in profile" EOF

chmod +x /usr/local/bin/check-sonar-gate.sh

# Usage: /usr/local/bin/check-sonar-gate.sh my-project http://sonarqube:9000 $TOKEN ```

SonarQube Quality Gate Checklist

CheckExpected
Coverage>= threshold (80%)
New bugs= 0 or < limit
New vulnerabilities= 0 or < limit
New code smells< threshold
Quality gate assignedCorrect gate for project
Quality profileRules appropriate
Exclusions configuredGenerated/test files excluded
New code periodBaseline set

Verify the Fix

```bash # After fixing SonarQube quality gate issues

# 1. Run analysis sonar-scanner // Analysis successful

# 2. Check quality gate curl -u token: "http://sonarqube/api/measures/component?component=my-project&metricKeys=alert_status" // OK

# 3. Verify coverage curl -u token: "http://sonarqube/api/measures/component?component=my-project&metricKeys=coverage" // >= threshold

# 4. Check new issues curl -u token: "http://sonarqube/api/issues/search?component=my-project&sinceLeakPeriod=true" // No critical issues

# 5. CI pipeline passes // Quality gate passed, pipeline continues

# 6. Review in UI # Dashboard shows green quality gate ```

  • [Fix SonarQube Analysis Not Running](/articles/fix-sonarqube-analysis-not-running)
  • [Fix Jenkins Build Stuck](/articles/fix-jenkins-build-stuck)
  • [Fix GitLab CI Pipeline Stuck](/articles/fix-gitlab-ci-pipeline-stuck)