goharbor/harbor · error · Exception
Internal dir for tls {} not exist
Error message
Internal dir for tls {} not exist What it means
ResolveData in src/pkg/scan/report/supported_mimes.go decodes raw report bytes into the model registered for the mime type in SupportedMimes. If the mime type IS supported but jsonData is zero-length it returns 'empty JSON data', because json.Unmarshal on empty input would only produce a less clear syntax error. Unsupported mime types deliberately return (nil, nil) and never reach this check.
Source
Thrown at make/photon/prepare/models.py:99
# 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))
def validate(self):
if not self.enabled:
# pass the validation if not enabled
return
if not internal_tls_dir.exists():
raise Exception('Internal dir for tls {} not exist'.format(internal_tls_dir))
for filename in self.required_filenames:
self._check(filename)
def prepare(self):
"""
Prepare moves certs in tls file to data volume with correct permission.
"""
if not self.enabled:
logging.info('internal tls NOT enabled...')
return
original_tls_dir = get_realpath(self.tls_dir)
if internal_tls_dir.exists():
rmtree(internal_tls_dir)
copytree(original_tls_dir, internal_tls_dir, symlinks=True)
for file in internal_tls_dir.iterdir():
if file.name.endswith('.key'):View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Length-check jsonData before calling ResolveData and treat empty data as an upstream fetch/storage failure
- Fix the producer that stored or returned the empty report body
- If a mime type is meant to bypass parsing, do not register it in SupportedMimes — unregistered mimes pass raw data through untouched
Example fix
// before
data, err := report.ResolveData(mime, body) // body may be empty
// after
if len(body) == 0 {
return nil, fmt.Errorf("report body for mime %s is empty", mime)
}
data, err := report.ResolveData(mime, body) Defensive patterns
Strategy: validation
Validate before calling
if len(jsonData) == 0 {
return nil, fmt.Errorf("no data to resolve for mime %s", mime)
}
return report.ResolveData(mime, jsonData) Try / catch
data, err := report.ResolveData(mime, jsonData)
if err != nil {
if strings.Contains(err.Error(), "empty JSON data") {
// data was fetched empty: fix the fetch, do not retry parse
return nil, fmt.Errorf("report body empty for %s", mime)
}
return nil, err
} Prevention
- Treat empty report bodies as fetch failures, not as parse inputs
- Remember unsupported mimes return (nil, nil) by design — only registered mimes reach the parser
- Store reports only after a successful non-empty read
When it happens
Trigger: Calling ResolveData(mime, nil) or ResolveData(mime, []byte{}) with a mime present in SupportedMimes — e.g. after fetching a report whose body came back empty.
Common situations: A scanner adapter returned 200 with an empty body; a database column holding an empty report blob; passing the wrong variable for the data parameter.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- File {} not exist
- Trace enabled but no trace exporter set
- 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
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/7ecf4c1257131026.
Report an issue: GitHub.