diff --git a/pkg/server/container_create.go b/pkg/server/container_create.go
index acb3c3688..e8ef19d83 100644
--- a/pkg/server/container_create.go
+++ b/pkg/server/container_create.go
@@ -227,11 +227,16 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
 	userstr, err := generateUserString(
 		securityContext.GetRunAsUsername(),
 		securityContext.GetRunAsUser(),
-		securityContext.GetRunAsGroup(),
-	)
+		securityContext.GetRunAsGroup())
+
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to generate user string")
 	}
+	if userstr == "" {
+		// Lastly, since no user override was passed via CRI try to set via OCI
+		// Image
+		userstr = image.ImageSpec.Config.User
+	}
 	if userstr != "" {
 		specOpts = append(specOpts, oci.WithUser(userstr))
 	}
@@ -589,7 +594,20 @@ func generateApparmorSpecOpts(apparmorProf string, privileged, apparmorEnabled b
 	}
 }
 
-// generateUserString generates valid user string based on OCI Image Spec v1.0.0.
+// generateUserString generates valid user string based on OCI Image Spec
+// v1.0.0.
+//
+// CRI defines that the following combinations are valid:
+//
+// (none) -> ""
+// username -> username
+// username, uid -> username
+// username, uid, gid -> username:gid
+// username, gid -> username:gid
+// uid -> uid
+// uid, gid -> uid:gid
+// gid -> error
+//
 // TODO(random-liu): Add group name support in CRI.
 func generateUserString(username string, uid, gid *runtime.Int64Value) (string, error) {
 	var userstr, groupstr string
diff --git a/pkg/server/container_create_test.go b/pkg/server/container_create_test.go
index 8c4a59bb3..4a20225ca 100644
--- a/pkg/server/container_create_test.go
+++ b/pkg/server/container_create_test.go
@@ -1231,3 +1231,74 @@ func TestDisableCgroup(t *testing.T) {
 	t.Log("cgroup path should be empty")
 	assert.Empty(t, spec.Linux.CgroupsPath)
 }
+
+func TestGenerateUserString(t *testing.T) {
+	type testcase struct {
+		// the name of the test case
+		name string
+
+		u        string
+		uid, gid *runtime.Int64Value
+
+		result        string
+		expectedError bool
+	}
+	testcases := []testcase{
+		{
+			name:   "Empty",
+			result: "",
+		},
+		{
+			name:   "Username Only",
+			u:      "testuser",
+			result: "testuser",
+		},
+		{
+			name:   "Username, UID",
+			u:      "testuser",
+			uid:    &runtime.Int64Value{Value: 1},
+			result: "testuser",
+		},
+		{
+			name:   "Username, UID, GID",
+			u:      "testuser",
+			uid:    &runtime.Int64Value{Value: 1},
+			gid:    &runtime.Int64Value{Value: 10},
+			result: "testuser:10",
+		},
+		{
+			name:   "Username, GID",
+			u:      "testuser",
+			gid:    &runtime.Int64Value{Value: 10},
+			result: "testuser:10",
+		},
+		{
+			name:   "UID only",
+			uid:    &runtime.Int64Value{Value: 1},
+			result: "1",
+		},
+		{
+			name:   "UID, GID",
+			uid:    &runtime.Int64Value{Value: 1},
+			gid:    &runtime.Int64Value{Value: 10},
+			result: "1:10",
+		},
+		{
+			name:          "GID only",
+			gid:           &runtime.Int64Value{Value: 10},
+			result:        "",
+			expectedError: true,
+		},
+	}
+	for _, tc := range testcases {
+		t.Run(tc.name, func(t *testing.T) {
+			r, err := generateUserString(tc.u, tc.uid, tc.gid)
+			if tc.expectedError {
+				assert.Error(t, err)
+			} else {
+				assert.NoError(t, err)
+			}
+			assert.Equal(t, tc.result, r)
+		})
+	}
+}
diff --git a/pkg/server/sandbox_run.go b/pkg/server/sandbox_run.go
index bbf9b15f5..b0189a39b 100644
--- a/pkg/server/sandbox_run.go
+++ b/pkg/server/sandbox_run.go
@@ -169,6 +169,11 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
 	if err != nil {
 		return nil, errors.Wrap(err, "failed to generate user string")
 	}
+	if userstr == "" {
+		// Lastly, since no user override was passed via CRI try to set via OCI
+		// Image
+		userstr = image.ImageSpec.Config.User
+	}
 	if userstr != "" {
 		specOpts = append(specOpts, oci.WithUser(userstr))
 	}