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

  1. Length-check the report string where it is produced (adapter response read) and surface the real upstream error instead of passing it on
  2. Guard uuid != "" && report != "" immediately before calling UpdateReportData
  3. 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

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


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/8611b95de80bbace. Report an issue: GitHub.