goharbor/harbor · error
empty JSON data
Error message
empty JSON data
What it means
Returned by CheckInReport.FromJSON when the job check-in message is empty. The scan job's check-in data must be a JSON object with digest, registration_uuid, mime_type and raw_report; an empty string is rejected before unmarshal.
Source
Thrown at src/pkg/scan/job.go:74
authorizationBearer = "Bearer"
authorizationBasic = "Basic"
service = "harbor-registry"
)
// CheckInReport defines model for checking in the scan report with specified mime.
type CheckInReport struct {
Digest string `json:"digest"`
RegistrationUUID string `json:"registration_uuid"`
MimeType string `json:"mime_type"`
RawReport string `json:"raw_report"`
}
// FromJSON parse json to CheckInReport
func (cir *CheckInReport) FromJSON(jsonData string) error {
if len(jsonData) == 0 {
return errors.New("empty JSON data")
}
return json.Unmarshal([]byte(jsonData), cir)
}
// ToJSON marshal CheckInReport to JSON
func (cir *CheckInReport) ToJSON() (string, error) {
jsonData, err := json.Marshal(cir)
if err != nil {
return "", errors.Wrap(err, "To JSON: CheckInReport")
}
return string(jsonData), nil
}
// Job for running scan in the job service with async way
type Job struct{}
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Make the adapter always check in a serialized CheckInReport JSON, even on failure paths
- Verify the adapter returns a non-empty body and no intermediary (proxy/gateway) strips it
- Check adapter logs for the check-in POST payload size and content
Example fix
// before
func (j *Job) CheckIn(msg string) { _ = cir.FromJSON(msg) } // msg == ""
// after
func (j *Job) CheckIn(msg string) error {
if len(msg) == 0 {
return errors.New("empty check-in data from scanner adapter")
}
return cir.FromJSON(msg)
} Defensive patterns
Strategy: validation
Validate before calling
if len(checkInMsg) == 0 {
return errors.New("scanner adapter checked in with empty report data")
}
var cir job.CheckInReport
if err := cir.FromJSON(checkInMsg); err != nil {
return err
} Prevention
- Adapters must always POST a serialized CheckInReport, including on error paths
- Watch proxy body-size limits that can truncate check-in payloads to empty
- Log check-in message length in adapter tests
When it happens
Trigger: The scanner adapter calls job check-in with an empty message string; the scan job's CheckIn callback receives an empty status message from the job service; adapter returns empty raw_report payload.
Common situations: Custom scanner adapters implemented against the job check-in API that post no message; truncation of large report payloads by proxies; version mismatch where the adapter's check-in contract differs from Harbor's.
Related errors
- Internal dir for tls {} not exist
- Trace enabled but no trace exporter set
- empty json data to parse
- check scan report timeout
- File {} not exist
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/dbf0ecce3148d47f.
Report an issue: GitHub.