goharbor/harbor · error · Exception
File {} not exist
Error message
File {} not exist What it means
Returned by basicManager.UpdateReportData in src/pkg/scan/report/manager.go when the vulnerability report manager is asked to persist a report whose JSON body is the empty string. Both uuid and report are validated before the DAO is touched, and an empty payload is refused because writing it would silently blank the stored report for that uuid. This is a pure argument-validation error, not a persistence failure.
Source
Thrown at make/photon/prepare/models.py:73
filename = '{}.{}'.format('_'.join(name_parts[:-2]), name_parts[-2])
if filename in self.required_filenames:
return os.path.join(self.data_volume, 'secret', 'tls', filename)
return object.__getattribute__(self, name)
def _check(self, filename: str):
"""
Check cert and key files are correct
"""
path = Path(os.path.join(internal_tls_dir, filename))
if not path.exists:
if filename == 'harbor_internal_ca.crt':
return
raise Exception('File {} not exist'.format(filename))
if not path.is_file:
raise Exception('invalid {}'.format(filename))
# check key file permission
if filename.endswith('.key') and not check_permission(path, mode=0o600):
raise Exception('key file {} permission is not 600'.format(filename))
# check certificate file
if filename.endswith('.crt'):
if not owner_can_read(path.stat().st_mode):
# check owner can read cert file
raise Exception('File {} should readable by owner'.format(filename))
if not san_existed(path):
# check SAN included
if filename == 'harbor_internal_ca.crt':
return
raise Exception('cert file {} should include SAN'.format(filename))View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Length-check the report string where it is produced (adapter response read) and surface the real upstream error instead of passing it on
- Guard uuid != "" && report != "" immediately before calling UpdateReportData
- If the intent was to clear a report, use the delete API instead — this method intentionally rejects empty payloads
Example fix
// before
err := mgr.UpdateReportData(ctx, uuid, report) // report may be ""
// after
if strings.TrimSpace(report) == "" {
return fmt.Errorf("scan report for %s is empty; refusing to store", uuid)
}
err := mgr.UpdateReportData(ctx, uuid, report) Defensive patterns
Strategy: validation
Validate before calling
if uuid == "" || strings.TrimSpace(report) == "" {
return fmt.Errorf("cannot update report data: uuid=%q payload_len=%d", uuid, len(report))
}
return mgr.UpdateReportData(ctx, uuid, report) Try / catch
if err := mgr.UpdateReportData(ctx, uuid, report); err != nil {
if strings.Contains(err.Error(), "missing report JSON data") {
// empty payload: fix the producer, do not retry with the same input
log.Printf("empty report body for uuid %s", uuid)
}
return err
} Prevention
- Treat an empty report body from any adapter as an error at fetch time, not at store time
- Validate string arguments at the boundary before handing them to manager APIs
- Never use UpdateReportData to blank out a stored report
When it happens
Trigger: Calling mgr.UpdateReportData(ctx, uuid, report) with report == "" — typically the string obtained from the scanner adapter's GetScanReport call came back empty, or the caller passed the wrong or never-assigned variable.
Common situations: A scanner adapter returned HTTP 200 with an empty body and the body-read error was swallowed upstream; a marshalling step produced an empty string; refactors that renamed the payload variable and left an empty one in place.
Related errors
- Internal dir for tls {} not exist
- Port number in metrics is not valid
- Jaeger Colector Endpoint or Agent host not set, must set one
- Jaeger Colector Endpoint and Agent host both set, only can s
- Trace enabled but no trace exporter set
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/8611b95de80bbace.
Report an issue: GitHub.