diff --git a/cmd/data-scanner.go b/cmd/data-scanner.go index 02ceed636..74a99bf47 100644 --- a/cmd/data-scanner.go +++ b/cmd/data-scanner.go @@ -1036,6 +1036,9 @@ type actionsAccountingFn func(oi ObjectInfo, sz, actualSz int64, sizeS *sizeSumm // The metadata will be compared to consensus on the object layer before any changes are applied. // If no metadata is supplied, -1 is returned if no action is taken. func (i *scannerItem) applyActions(ctx context.Context, objAPI ObjectLayer, objInfos []ObjectInfo, lr lock.Retention, sizeS *sizeSummary, fn actionsAccountingFn) { + if len(objInfos) == 0 { + return + } healActions := func(oi ObjectInfo, actualSz int64) int64 { size := actualSz if i.heal.enabled { diff --git a/cmd/data-scanner_test.go b/cmd/data-scanner_test.go index 367dfc666..0c4fdf507 100644 --- a/cmd/data-scanner_test.go +++ b/cmd/data-scanner_test.go @@ -245,6 +245,12 @@ func TestApplyNewerNoncurrentVersionsLimit(t *testing.T) { wants: nil, wantExpired: []ObjectToDelete{{ObjectV: ObjectV{ObjectName: obj, VersionID: allVersExpObjInfos[0].VersionID}}}, }, + { + // When no versions are present, in practice this could be an object with only free versions + objInfos: nil, + wants: nil, + wantExpired: nil, + }, } for i, test := range tests { t.Run(fmt.Sprintf("TestApplyNewerNoncurrentVersionsLimit-%d", i), func(t *testing.T) { diff --git a/internal/bucket/lifecycle/evaluator.go b/internal/bucket/lifecycle/evaluator.go index adc5ab233..ec6f04e64 100644 --- a/internal/bucket/lifecycle/evaluator.go +++ b/internal/bucket/lifecycle/evaluator.go @@ -146,6 +146,9 @@ loop: // Eval will return a lifecycle event for each object in objs func (e *Evaluator) Eval(objs []ObjectOpts) ([]Event, error) { + if len(objs) == 0 { + return nil, nil + } if len(objs) != objs[0].NumVersions { return nil, fmt.Errorf("number of versions mismatch, expected %d, got %d", objs[0].NumVersions, len(objs)) } diff --git a/internal/bucket/lifecycle/evaluator_test.go b/internal/bucket/lifecycle/evaluator_test.go index f85130bf1..8225fcd68 100644 --- a/internal/bucket/lifecycle/evaluator_test.go +++ b/internal/bucket/lifecycle/evaluator_test.go @@ -144,6 +144,12 @@ func TestNewerNoncurrentVersions(t *testing.T) { t.Fatalf("test-%d: got %v, want %v", i+1, gotEvents[i], wantEvents[i]) } } + + // Test with zero versions + events, err := evaluator.Eval(nil) + if len(events) != 0 || err != nil { + t.Fatal("expected no events nor error") + } } func TestEmptyEvaluator(t *testing.T) {