diff --git a/pkg/core/object/fmt.go b/pkg/core/object/fmt.go
index 483a9e6be8..a8c82f967a 100644
--- a/pkg/core/object/fmt.go
+++ b/pkg/core/object/fmt.go
@@ -61,6 +61,8 @@ var errNoExpirationEpoch = errors.New("missing expiration epoch attribute")
 
 var errTombstoneExpiration = errors.New("tombstone body and header contain different expiration values")
 
+var errEmptySGMembers = errors.New("storage group with empty members list")
+
 func defaultCfg() *cfg {
 	return new(cfg)
 }
@@ -227,6 +229,22 @@ func (v *FormatValidator) ValidateContent(o *object.Object) error {
 		if err := sg.Unmarshal(o.Payload()); err != nil {
 			return fmt.Errorf("(%T) could not unmarshal SG content: %w", v, err)
 		}
+
+		mm := sg.Members()
+		lenMM := len(mm)
+		if lenMM == 0 {
+			return errEmptySGMembers
+		}
+
+		uniqueFilter := make(map[oid.ID]struct{}, lenMM)
+
+		for i := 0; i < lenMM; i++ {
+			if _, alreadySeen := uniqueFilter[mm[i]]; alreadySeen {
+				return fmt.Errorf("storage group contains non-unique member: %s", mm[i])
+			}
+
+			uniqueFilter[mm[i]] = struct{}{}
+		}
 	case object.TypeLock:
 		if len(o.Payload()) == 0 {
 			return errors.New("empty payload in lock")
diff --git a/pkg/core/object/fmt_test.go b/pkg/core/object/fmt_test.go
index f2fcad002a..3bc9eed056 100644
--- a/pkg/core/object/fmt_test.go
+++ b/pkg/core/object/fmt_test.go
@@ -156,25 +156,42 @@ func TestFormatValidator_Validate(t *testing.T) {
 		obj := object.New()
 		obj.SetType(object.TypeStorageGroup)
 
-		require.Error(t, v.ValidateContent(obj))
+		t.Run("empty payload", func(t *testing.T) {
+			require.Error(t, v.ValidateContent(obj))
+		})
 
 		var content storagegroup.StorageGroup
+		content.SetExpirationEpoch(1) // some non-default value
 
-		data, err := content.Marshal()
-		require.NoError(t, err)
+		t.Run("empty members", func(t *testing.T) {
+			data, err := content.Marshal()
+			require.NoError(t, err)
 
-		obj.SetPayload(data)
+			obj.SetPayload(data)
+			require.ErrorIs(t, v.ValidateContent(obj), errEmptySGMembers)
+		})
 
-		require.Error(t, v.ValidateContent(obj))
+		t.Run("non-unique members", func(t *testing.T) {
+			id := oidtest.ID()
 
-		content.SetMembers([]oid.ID{oidtest.ID()})
+			content.SetMembers([]oid.ID{id, id})
 
-		data, err = content.Marshal()
-		require.NoError(t, err)
+			data, err := content.Marshal()
+			require.NoError(t, err)
 
-		obj.SetPayload(data)
+			obj.SetPayload(data)
+			require.Error(t, v.ValidateContent(obj))
+		})
 
-		require.NoError(t, v.ValidateContent(obj))
+		t.Run("correct SG", func(t *testing.T) {
+			content.SetMembers([]oid.ID{oidtest.ID(), oidtest.ID()})
+
+			data, err := content.Marshal()
+			require.NoError(t, err)
+
+			obj.SetPayload(data)
+			require.NoError(t, v.ValidateContent(obj))
+		})
 	})
 
 	t.Run("expiration", func(t *testing.T) {