Trivy’s default behavior is to report all detected vulnerabilities, but you can, and absolutely should, filter this output to focus on what matters most.

Let’s see Trivy in action, scanning a sample image with a mix of severity vulnerabilities, and then how to filter it.

# First, scan an image and save the output to a file
trivy image --format json --output scan_results.json alpine:latest

# Now, let's look at a snippet of scan_results.json (simplified for clarity)
# You'll see vulnerabilities across different severities:
# {
#   "Results": [
#     {
#       "Target": "alpine:latest (linux/amd64)",
#       "Vulnerabilities": [
#         {
#           "VulnerabilityID": "CVE-2023-XXXX",
#           "PkgName": "openssl",
#           "InstalledVersion": "1.1.1t-r3",
#           "Severity": "CRITICAL",
#           "Title": "...",
#           "Description": "..."
#         },
#         {
#           "VulnerabilityID": "CVE-2023-YYYY",
#           "PkgName": "curl",
#           "InstalledVersion": "7.87.0-r0",
#           "Severity": "HIGH",
#           "Title": "...",
#           "Description": "..."
#         },
#         {
#           "VulnerabilityID": "CVE-2023-ZZZZ",
#           "PkgName": "busybox",
#           "InstalledVersion": "1.35.0-r1",
#           "Severity": "MEDIUM",
#           "Title": "...",
#           "Description": "..."
#         },
#         {
#           "VulnerabilityID": "CVE-2023-AAAA",
#           "PkgName": "zlib",
#           "InstalledVersion": "1:1.2.13-r0",
#           "Severity": "LOW",
#           "Title": "...",
#           "Description": "..."
#         }
#       ]
#     }
#   ]
# }

The problem Trivy solves is information overload. In any given container image, there can be hundreds or even thousands of detected vulnerabilities. Manually sifting through this list to identify the most pressing issues is impractical and error-prone. Trivy’s severity filtering allows you to cut through the noise and prioritize remediation efforts on the vulnerabilities that pose the greatest risk to your applications.

Internally, Trivy consults vulnerability databases (like NVD, Red Hat’s CVE database, etc.) and compares the software packages and their versions found in your target (container image, filesystem, etc.) against known vulnerabilities. Each vulnerability is assigned a severity level: CRITICAL, HIGH, MEDIUM, LOW, and UNKNOWN. The filtering mechanism simply acts as a post-processing step on this list of detected vulnerabilities, discarding any that do not meet your specified criteria.

The primary lever you control is the --severity flag. This flag accepts a comma-separated list of severities you wish to include in the output.

# To see only HIGH and CRITICAL vulnerabilities:
trivy image --severity HIGH,CRITICAL alpine:latest

# To see only CRITICAL vulnerabilities:
trivy image --severity CRITICAL alpine:latest

# You can also use shorthand for common thresholds:
# --severity-level HIGH is equivalent to --severity HIGH,CRITICAL
trivy image --severity-level HIGH alpine:latest

This filtering isn’t just for human readability; it’s crucial for automation. When integrating Trivy into CI/CD pipelines, you’ll often want to fail the build if any CRITICAL or HIGH vulnerabilities are found. The --exit-on-severity flag is perfect for this.

# This command will exit with a non-zero status code if any CRITICAL or HIGH vulnerabilities are found.
# This is ideal for CI/CD gates.
trivy image --exit-on-severity HIGH alpine:latest

When you use --severity or --severity-level, Trivy doesn’t just hide the lower-severity vulnerabilities; it completely omits them from the scan results. This means that if you filter for HIGH and CRITICAL, Trivy effectively stops processing or reporting on MEDIUM, LOW, and UNKNOWN vulnerabilities for the purposes of that specific output. The underlying scan still identifies them, but the output formatting and exit conditions are applied to this filtered set.

The next logical step after filtering is to understand the specific CVEs and their associated packages, often by outputting in a machine-readable format like JSON and then processing that further.

Want structured learning?

Take the full Trivy course →