diff --git a/api/src/main/java/io/grpc/Status.java b/api/src/main/java/io/grpc/Status.java
index 38cd9581f8e..0a9e5260e99 100644
--- a/api/src/main/java/io/grpc/Status.java
+++ b/api/src/main/java/io/grpc/Status.java
@@ -656,8 +656,14 @@ private static String parseAsciiStringSlow(byte[] value) {
    * additional fields may be added to Status in the future.
    */
   @Override
-  public boolean equals(Object obj) {
-    return super.equals(obj);
+  public boolean equals(Object o) {
+    if (!(o instanceof Status)) {
+      return false;
+    }
+    Status status = (Status) o;
+    return code == status.code
+            && Objects.equal(description, status.description)
+            && Objects.equal(cause, status.cause);
   }
 
   /**
@@ -667,6 +673,6 @@ public boolean equals(Object obj) {
    */
   @Override
   public int hashCode() {
-    return super.hashCode();
+    return Objects.hashCode(code, description, cause);
   }
 }
diff --git a/api/src/test/java/io/grpc/StatusOrTest.java b/api/src/test/java/io/grpc/StatusOrTest.java
index f63a314a2bb..09de09de4e6 100644
--- a/api/src/test/java/io/grpc/StatusOrTest.java
+++ b/api/src/test/java/io/grpc/StatusOrTest.java
@@ -61,6 +61,8 @@ public void equals_differentStatuses() {
   @Test
   public void equals_sameStatuses() {
     assertThat(StatusOr.fromStatus(Status.ABORTED)).isEqualTo(StatusOr.fromStatus(Status.ABORTED));
+    assertThat(StatusOr.fromStatus(Status.ABORTED.withDescription("aborted")))
+            .isEqualTo(StatusOr.fromStatus(Status.ABORTED.withDescription("aborted")));
   }
 
   @Test
diff --git a/api/src/test/java/io/grpc/StatusTest.java b/api/src/test/java/io/grpc/StatusTest.java
index 5c8a1b2ae86..f02711206ea 100644
--- a/api/src/test/java/io/grpc/StatusTest.java
+++ b/api/src/test/java/io/grpc/StatusTest.java
@@ -17,6 +17,7 @@
 package io.grpc;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertSame;
 
 import io.grpc.Status.Code;
@@ -51,6 +52,16 @@ public void sameCauseReturnsSelf() {
     assertSame(Status.CANCELLED, Status.CANCELLED.withCause(null));
   }
 
+  @Test
+  public void equalsStatus() {
+    IllegalStateException ex = new IllegalStateException("The operation was aborted");
+    assertEquals(Status.ABORTED.withDescription("The operation was aborted")
+                    .withCause(ex),
+            Status.ABORTED.withDescription("The operation was aborted")
+                    .withCause(ex));
+    assertNotEquals(Status.ABORTED.withDescription("The operation was aborted"), null);
+  }
+
   @Test
   public void sameDescriptionReturnsSelf() {
     assertSame(Status.CANCELLED, Status.CANCELLED.withDescription(null));
@@ -58,8 +69,8 @@ public void sameDescriptionReturnsSelf() {
   }
 
   @Test
-  public void useObjectHashCode() {
-    assertEquals(Status.CANCELLED.hashCode(), System.identityHashCode(Status.CANCELLED));
+  public void notUseObjectHashCode() {
+    assertNotEquals(Status.CANCELLED.hashCode(), System.identityHashCode(Status.CANCELLED));
   }
 
   @Test