Bug description
A reimport can reactivate a previously mitigated finding even when that finding is marked as a duplicate. This can result in findings with an invalid/contradictory state:
active = true
verified = true
duplicate = true
duplicate_finding = <original finding>
DefectDojo documentation says duplicate findings are set inactive by default so that there is only one active finding to remediate. However, the reactivation path appears able to set a duplicate finding back to active/verified without clearing or accounting for the duplicate state.
This creates an effectively dead-locked finding state. When trying to edit such a finding, DefectDojo rejects the form with:
Duplicate findings cannot be verified or active
That validation is correct, but the reimport/reactivation logic has already created the invalid state.
Example state observed:
{
"active": true,
"verified": true,
"duplicate": true,
"duplicate_finding": 43558,
"display_status": "Active, Verified, Duplicate"
}
Steps to reproduce
Steps to reproduce the behavior:
- Import a scan that creates finding A.
- Import or reimport another scan in the same deduplication scope that creates finding B as a duplicate of finding A.
- Ensure finding B is marked as a duplicate of finding A.
- Reimport a scan where finding B is no longer present, with
close_old_findings = true, so finding B is closed/mitigated.
- Reimport a later scan where finding B appears again, with
do_not_reactivate = false, active = true, and verified = true.
- Observe that finding B is reactivated while still being marked as duplicate.
- Try to edit finding B.
- See the validation error:
Duplicate findings cannot be verified or active
In our environment, this is triggered by Trivy Operator scan reimports using /api/v2/reimport-scan/ with:
scan_type = Trivy Operator Scan
close_old_findings = true
do_not_reactivate = false
active = true
verified = true
Observed flow from the importer history:
- Finding is marked duplicate of another finding.
- Reimport closes/mitigates the duplicate finding when it is absent from the scan.
- Later reimport sees the finding again and reactivates it.
- The finding becomes
Active, Verified, Duplicate.
Expected behavior
Reimport reactivation should not create a finding state that DefectDojo itself rejects as invalid.
When a mitigated finding is reactivated and it is marked as duplicate, DefectDojo should either:
- keep the duplicate finding inactive, or
- clear the duplicate relationship before reactivating it, if that is the intended lifecycle, or
- skip reactivation and log/add a note explaining that duplicate findings cannot be active/verified.
The key expectation is that duplicate=true findings should not end up with active=true or verified=true.
Deployment method (select with an X)
Environment information
- Operating System: Kubernetes
- Docker Compose or Helm version (Output of
docker compose version or helm version): N/A
- DefectDojo version (see footer) or commit message: v. 2.58.3
Logs
No application traceback was observed. The issue is a data/state consistency problem caused by reimport reactivation.
The UI/form validation error when trying to edit the resulting finding is:
Duplicate findings cannot be verified or active
Sample scan files
Not available yet. The issue was observed with repeated Trivy Operator scan reimports.
The relevant import settings were:
{
"active": true,
"verified": true,
"close_old_findings": true,
"do_not_reactivate": false,
"scan_type": "Trivy Operator Scan"
}
Screenshots
Not included.
Additional context (optional)
DefectDojo documentation says:
Duplicate Findings are set as Inactive by default.
Docs: https://docs.defectdojo.com/triage_findings/finding_deduplication/about_deduplication/
The finding edit form rejects this state with:
if (cleaned_data["active"] or cleaned_data["verified"]) and cleaned_data["duplicate"]:
msg = "Duplicate findings cannot be verified or active"
raise forms.ValidationError(msg)
Source: https://github.com/DefectDojo/django-DefectDojo/blob/master/dojo/forms.py
The likely problematic path is the reimport reactivation logic for mitigated findings, where a previously mitigated finding is made active/verified again without checking whether it is marked duplicate.
This matters because:
- Duplicate findings show up as active work even though duplicates are expected to be inactive.
- Metrics and dashboards overcount active vulnerabilities.
- The finding is difficult to correct through the UI because the edit form rejects the current state.
- The behavior is especially visible with recurring scanner integrations such as Trivy Operator, where findings repeatedly disappear/reappear across reimports.
Suggested fix:
Before reactivating a mitigated finding during reimport, check whether the existing finding is a duplicate.
If existing_finding.duplicate is true, DefectDojo should not set it active/verified during reactivation. Alternatively, it should explicitly resolve/clear the duplicate relationship before reactivation if that is the intended model.
A regression test would be useful for:
- Create finding A.
- Create finding B as duplicate of A.
- Mitigate/close finding B via reimport.
- Reimport a scan that matches finding B again.
- Assert finding B does not end up as
active=true, duplicate=true or verified=true, duplicate=true.
Bug description
A reimport can reactivate a previously mitigated finding even when that finding is marked as a duplicate. This can result in findings with an invalid/contradictory state:
active = trueverified = trueduplicate = trueduplicate_finding = <original finding>DefectDojo documentation says duplicate findings are set inactive by default so that there is only one active finding to remediate. However, the reactivation path appears able to set a duplicate finding back to active/verified without clearing or accounting for the duplicate state.
This creates an effectively dead-locked finding state. When trying to edit such a finding, DefectDojo rejects the form with:
That validation is correct, but the reimport/reactivation logic has already created the invalid state.
Example state observed:
{ "active": true, "verified": true, "duplicate": true, "duplicate_finding": 43558, "display_status": "Active, Verified, Duplicate" }Steps to reproduce
Steps to reproduce the behavior:
close_old_findings = true, so finding B is closed/mitigated.do_not_reactivate = false,active = true, andverified = true.In our environment, this is triggered by Trivy Operator scan reimports using
/api/v2/reimport-scan/with:scan_type = Trivy Operator Scanclose_old_findings = truedo_not_reactivate = falseactive = trueverified = trueObserved flow from the importer history:
Active, Verified, Duplicate.Expected behavior
Reimport reactivation should not create a finding state that DefectDojo itself rejects as invalid.
When a mitigated finding is reactivated and it is marked as duplicate, DefectDojo should either:
The key expectation is that
duplicate=truefindings should not end up withactive=trueorverified=true.Deployment method (select with an
X)Environment information
docker compose versionorhelm version): N/ALogs
No application traceback was observed. The issue is a data/state consistency problem caused by reimport reactivation.
The UI/form validation error when trying to edit the resulting finding is:
Sample scan files
Not available yet. The issue was observed with repeated Trivy Operator scan reimports.
The relevant import settings were:
{ "active": true, "verified": true, "close_old_findings": true, "do_not_reactivate": false, "scan_type": "Trivy Operator Scan" }Screenshots
Not included.
Additional context (optional)
DefectDojo documentation says:
Docs: https://docs.defectdojo.com/triage_findings/finding_deduplication/about_deduplication/
The finding edit form rejects this state with:
Source: https://github.com/DefectDojo/django-DefectDojo/blob/master/dojo/forms.py
The likely problematic path is the reimport reactivation logic for mitigated findings, where a previously mitigated finding is made active/verified again without checking whether it is marked duplicate.
This matters because:
Suggested fix:
Before reactivating a mitigated finding during reimport, check whether the existing finding is a duplicate.
If
existing_finding.duplicateis true, DefectDojo should not set it active/verified during reactivation. Alternatively, it should explicitly resolve/clear the duplicate relationship before reactivation if that is the intended model.A regression test would be useful for:
active=true, duplicate=trueorverified=true, duplicate=true.