diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
similarity index 97%
rename from hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
index 80463e3a7a..4af7d568df 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
@@ -125,6 +125,11 @@ public enum ResultCodes {
     COMPLETE_MULTIPART_UPLOAD_FAILED,
     ENTITY_TOO_SMALL,
     ABORT_MULTIPART_UPLOAD_FAILED,
-    INVALID_REQUEST;
+    INVALID_REQUEST,
+    INVALID_AUTH_METHOD,
+    INVALID_TOKEN,
+    TOKEN_EXPIRED,
+    TOKEN_ERROR_OTHER,
+    UNKNOWN
   }
 }
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/package-info.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/package-info.java
similarity index 100%
rename from hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/exceptions/package-info.java
rename to hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/package-info.java
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerSecurityProtocol.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerSecurityProtocol.java
index 15873d0b97..3e90899bd9 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerSecurityProtocol.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerSecurityProtocol.java
@@ -17,13 +17,13 @@
  */
 package org.apache.hadoop.ozone.om.protocol;
 
-import java.io.IOException;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.io.retry.Idempotent;
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.security.KerberosInfo;
 import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
 
 /**
  * Security protocol for a secure OzoneManager.
@@ -37,31 +37,31 @@ public interface OzoneManagerSecurityProtocol {
    *
    * @param renewer the designated renewer for the token
    * @return Token<OzoneDelegationTokenSelector>
-   * @throws IOException
+   * @throws OMException
    */
   @Idempotent
   Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
-      throws IOException;
+      throws OMException;
 
   /**
    * Renew an existing delegation token.
    *
    * @param token delegation token obtained earlier
    * @return the new expiration time
-   * @throws IOException
+   * @throws OMException
    */
   @Idempotent
   long renewDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws IOException;
+      throws OMException;
 
   /**
    * Cancel an existing delegation token.
    *
    * @param token delegation token
-   * @throws IOException
+   * @throws OMException
    */
   @Idempotent
   void cancelDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws IOException;
+      throws OMException;
 
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index e833f5e428..158395360e 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -41,7 +41,7 @@
 import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
 import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
 import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.protocol.proto
     .OzoneManagerProtocolProtos.AllocateBlockRequest;
 import org.apache.hadoop.ozone.protocol.proto
@@ -189,6 +189,12 @@
     .OzoneManagerProtocolProtos.CancelDelegationTokenResponseProto;
 import org.apache.hadoop.security.token.Token;
 
+import static org.apache.hadoop.ozone.om.exceptions.OMException.*;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_ERROR_OTHER;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.UNKNOWN;
+import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.OK;
+import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status.ACCESS_DENIED;
+
 /**
  *  The client side implementation of OzoneManagerProtocol.
  */
@@ -288,7 +294,7 @@ public void createVolume(OmVolumeArgs args) throws IOException {
     CreateVolumeResponse resp = submitRequest(omRequest)
         .getCreateVolumeResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Volume creation failed, error:" + resp.getStatus());
     }
@@ -314,7 +320,7 @@ public void setOwner(String volume, String owner) throws IOException {
     SetVolumePropertyResponse resp = submitRequest(omRequest)
         .getSetVolumePropertyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Volume owner change failed, error:" + resp.getStatus());
     }
@@ -340,7 +346,7 @@ public void setQuota(String volume, long quota) throws IOException {
     SetVolumePropertyResponse resp = submitRequest(omRequest)
         .getSetVolumePropertyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Volume quota change failed, error:" + resp.getStatus());
     }
@@ -369,9 +375,9 @@ public boolean checkVolumeAccess(String volume, OzoneAclInfo userAcl) throws
     CheckVolumeAccessResponse resp = submitRequest(omRequest)
         .getCheckVolumeAccessResponse();
 
-    if (resp.getStatus() == Status.ACCESS_DENIED) {
+    if (resp.getStatus() == ACCESS_DENIED) {
       return false;
-    } else if (resp.getStatus() == Status.OK) {
+    } else if (resp.getStatus() == OK) {
       return true;
     } else {
       throw new
@@ -397,7 +403,7 @@ public OmVolumeArgs getVolumeInfo(String volume) throws IOException {
 
     InfoVolumeResponse resp = submitRequest(omRequest).getInfoVolumeResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Info Volume failed, error:" + resp.getStatus());
     }
@@ -422,7 +428,7 @@ public void deleteVolume(String volume) throws IOException {
     DeleteVolumeResponse resp = submitRequest(omRequest)
         .getDeleteVolumeResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Delete Volume failed, error:" + resp.getStatus());
     }
@@ -490,7 +496,7 @@ private List<OmVolumeArgs> listVolume(ListVolumeRequest request)
 
     ListVolumeResponse resp = submitRequest(omRequest).getListVolumeResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("List volume failed, error: "
           + resp.getStatus());
     }
@@ -520,7 +526,7 @@ public void createBucket(OmBucketInfo bucketInfo) throws IOException {
     CreateBucketResponse resp = submitRequest(omRequest)
         .getCreateBucketResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Bucket creation failed, error: "
           + resp.getStatus());
     }
@@ -548,7 +554,7 @@ public OmBucketInfo getBucketInfo(String volume, String bucket)
 
     InfoBucketResponse resp = submitRequest(omRequest).getInfoBucketResponse();
 
-    if (resp.getStatus() == Status.OK) {
+    if (resp.getStatus() == OK) {
       return OmBucketInfo.getFromProtobuf(resp.getBucketInfo());
     } else {
       throw new IOException("Info Bucket failed, error: "
@@ -576,7 +582,7 @@ public void setBucketProperty(OmBucketArgs args)
     SetBucketPropertyResponse resp = submitRequest(omRequest)
         .getSetBucketPropertyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Setting bucket property failed, error: "
           + resp.getStatus());
     }
@@ -614,7 +620,7 @@ public List<OmBucketInfo> listBuckets(String volumeName,
     ListBucketsResponse resp = submitRequest(omRequest)
         .getListBucketsResponse();
 
-    if (resp.getStatus() == Status.OK) {
+    if (resp.getStatus() == OK) {
       buckets.addAll(
           resp.getBucketInfoList().stream()
               .map(OmBucketInfo::getFromProtobuf)
@@ -677,7 +683,7 @@ public OpenKeySession openKey(OmKeyArgs args) throws IOException {
 
     CreateKeyResponse resp = submitRequest(omRequest).getCreateKeyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Create key failed, error:" + resp.getStatus());
     }
     return new OpenKeySession(resp.getID(),
@@ -703,7 +709,7 @@ public OmKeyLocationInfo allocateBlock(OmKeyArgs args, long clientId)
     AllocateBlockResponse resp = submitRequest(omRequest)
         .getAllocateBlockResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Allocate block failed, error:" +
           resp.getStatus());
     }
@@ -733,7 +739,7 @@ public void commitKey(OmKeyArgs args, long clientId)
 
     CommitKeyResponse resp = submitRequest(omRequest).getCommitKeyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Commit key failed, error:" +
           resp.getStatus());
     }
@@ -756,7 +762,7 @@ public OmKeyInfo lookupKey(OmKeyArgs args) throws IOException {
 
     LookupKeyResponse resp = submitRequest(omRequest).getLookupKeyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Lookup key failed, error:" +
           resp.getStatus());
     }
@@ -780,7 +786,7 @@ public void renameKey(OmKeyArgs args, String toKeyName) throws IOException {
 
     RenameKeyResponse resp = submitRequest(omRequest).getRenameKeyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Rename key failed, error:" +
           resp.getStatus());
     }
@@ -807,7 +813,7 @@ public void deleteKey(OmKeyArgs args) throws IOException {
 
     DeleteKeyResponse resp = submitRequest(omRequest).getDeleteKeyResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Delete key failed, error:" +
           resp.getStatus());
     }
@@ -831,7 +837,7 @@ public void deleteBucket(String volume, String bucket) throws IOException {
     DeleteBucketResponse resp = submitRequest(omRequest)
         .getDeleteBucketResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new
           IOException("Delete Bucket failed, error:" + resp.getStatus());
     }
@@ -865,7 +871,7 @@ public List<OmKeyInfo> listKeys(String volumeName, String bucketName,
 
     ListKeysResponse resp = submitRequest(omRequest).getListKeysResponse();
 
-    if (resp.getStatus() == Status.OK) {
+    if (resp.getStatus() == OK) {
       keys.addAll(
           resp.getKeyInfoList().stream()
               .map(OmKeyInfo::getFromProtobuf)
@@ -892,7 +898,7 @@ public void createS3Bucket(String userName, String s3BucketName)
     S3CreateBucketResponse resp = submitRequest(omRequest)
         .getCreateS3BucketResponse();
 
-    if(resp.getStatus() != Status.OK) {
+    if(resp.getStatus() != OK) {
       throw new IOException("Creating S3 bucket failed, error: "
           + resp.getStatus());
     }
@@ -912,7 +918,7 @@ public void deleteS3Bucket(String s3BucketName) throws IOException {
     S3DeleteBucketResponse resp = submitRequest(omRequest)
         .getDeleteS3BucketResponse();
 
-    if(resp.getStatus() != Status.OK) {
+    if(resp.getStatus() != OK) {
       throw new IOException("Creating S3 bucket failed, error: "
           + resp.getStatus());
     }
@@ -933,7 +939,7 @@ public String getOzoneBucketMapping(String s3BucketName)
     S3BucketInfoResponse resp = submitRequest(omRequest)
         .getInfoS3BucketResponse();
 
-    if(resp.getStatus() != Status.OK) {
+    if(resp.getStatus() != OK) {
       throw new IOException("GetOzoneBucketMapping failed, error:" + resp
           .getStatus());
     }
@@ -963,7 +969,7 @@ public List<OmBucketInfo> listS3Buckets(String userName, String startKey,
     S3ListBucketsResponse resp = submitRequest(omRequest)
         .getListS3BucketsResponse();
 
-    if (resp.getStatus() == Status.OK) {
+    if (resp.getStatus() == OK) {
       buckets.addAll(
           resp.getBucketInfoList().stream()
               .map(OmBucketInfo::getFromProtobuf)
@@ -986,7 +992,7 @@ public S3SecretValue getS3Secret(String kerberosID) throws IOException {
     final GetS3SecretResponse resp = submitRequest(omRequest)
         .getGetS3SecretResponse();
 
-    if(resp.getStatus() != Status.OK) {
+    if(resp.getStatus() != OK) {
       throw new IOException("Fetch S3 Secret failed, error: " +
           resp.getStatus());
     } else {
@@ -1022,7 +1028,7 @@ public OmMultipartInfo initiateMultipartUpload(OmKeyArgs omKeyArgs) throws
     MultipartInfoInitiateResponse resp = submitRequest(omRequest)
         .getInitiateMultiPartUploadResponse();
 
-    if (resp.getStatus() != Status.OK) {
+    if (resp.getStatus() != OK) {
       throw new IOException("Initiate Multipart upload failed, error:" + resp
           .getStatus());
     }
@@ -1064,7 +1070,7 @@ public OmMultipartCommitUploadPartInfo commitMultipartUploadPart(
     MultipartCommitUploadPartResponse response = submitRequest(omRequest)
         .getCommitMultiPartUploadResponse();
 
-    if (response.getStatus() != Status.OK) {
+    if (response.getStatus() != OK) {
       throw new IOException("Commit multipart upload part key failed, error:"
           + response.getStatus());
     }
@@ -1099,7 +1105,7 @@ public OmMultipartUploadCompleteInfo completeMultipartUpload(
     MultipartUploadCompleteResponse response = submitRequest(omRequest)
         .getCompleteMultiPartUploadResponse();
 
-    if (response.getStatus() != Status.OK) {
+    if (response.getStatus() != OK) {
       throw new IOException("Complete multipart upload failed, error:" +
           response.getStatus());
     }
@@ -1130,7 +1136,7 @@ public void abortMultipartUpload(OmKeyArgs omKeyArgs) throws IOException {
     MultipartUploadAbortResponse response =
         submitRequest(omRequest).getAbortMultiPartUploadResponse();
 
-    if (response.getStatus() != Status.OK) {
+    if (response.getStatus() != OK) {
       throw new IOException("Abort multipart upload failed, error:" +
           response.getStatus());
     }
@@ -1147,7 +1153,7 @@ public List<ServiceInfo> getServiceList() throws IOException {
     final ServiceListResponse resp = submitRequest(omRequest)
         .getServiceListResponse();
 
-    if (resp.getStatus() == Status.OK) {
+    if (resp.getStatus() == OK) {
       return resp.getServiceInfoList().stream()
           .map(ServiceInfo::getFromProtobuf)
           .collect(Collectors.toList());
@@ -1162,11 +1168,11 @@ public List<ServiceInfo> getServiceList() throws IOException {
    *
    * @param renewer the designated renewer for the token
    * @return Token<OzoneDelegationTokenSelector>
-   * @throws IOException
+   * @throws OMException
    */
   @Override
   public Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
-      throws IOException {
+      throws OMException {
     GetDelegationTokenRequestProto req = GetDelegationTokenRequestProto
         .newBuilder()
         .setRenewer(renewer == null ? "" : renewer.toString())
@@ -1176,15 +1182,23 @@ public Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
         .setGetDelegationTokenRequest(req)
         .build();
 
-    final GetDelegationTokenResponseProto resp = submitRequest(omRequest)
-        .getGetDelegationTokenResponse();
-    if (resp.getStatus() == Status.OK) {
-       return resp.getResponse().hasToken() ?
-          OMPBHelper.convertToDelegationToken(resp.getResponse().getToken())
-           : null;
-    }  else {
-      throw new IOException("Get Delegation Token failed, error : " + resp
-          .getStatus());
+    final GetDelegationTokenResponseProto resp;
+    try {
+      resp = submitRequest(omRequest).getGetDelegationTokenResponse();
+
+      if (resp.getStatus() == OK) {
+        return resp.getResponse().hasToken() ?
+            OMPBHelper.convertToDelegationToken(resp.getResponse().getToken())
+            : null;
+      }
+      throw new OMException("Get delegation token failed with response:"
+          + resp.getStatus(), toResultStatus(resp.getStatus()));
+    } catch (IOException e) {
+      if(e instanceof OMException) {
+        throw (OMException)e;
+      }
+      throw new OMException("Get delegation token failed.", e,
+          TOKEN_ERROR_OTHER);
     }
   }
 
@@ -1193,11 +1207,10 @@ public Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
    *
    * @param token delegation token obtained earlier
    * @return the new expiration time
-   * @throws IOException
    */
   @Override
   public long renewDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws IOException {
+      throws OMException {
     RenewDelegationTokenRequestProto req =
         RenewDelegationTokenRequestProto.newBuilder().
             setToken(OMPBHelper.convertToTokenProto(token)).
@@ -1207,13 +1220,21 @@ public long renewDelegationToken(Token<OzoneTokenIdentifier> token)
         .setRenewDelegationTokenRequest(req)
         .build();
 
-    final RenewDelegationTokenResponseProto resp = submitRequest(omRequest)
-        .getRenewDelegationTokenResponse();
-    if (resp.getStatus() == Status.OK) {
-      return resp.getResponse().getNewExpiryTime();
-    }  else {
-      throw new IOException("Renew Delegation Token failed, error : " + resp
-          .getStatus());
+    final RenewDelegationTokenResponseProto resp;
+    try {
+      resp = submitRequest(omRequest)
+          .getRenewDelegationTokenResponse();
+      if (resp.getStatus() == OK) {
+        return resp.getResponse().getNewExpiryTime();
+      }
+      throw new OMException("Renew delegation token failed with response:"
+          + resp.getStatus(), toResultStatus(resp.getStatus()));
+    } catch (IOException e) {
+      if(e instanceof OMException) {
+        throw (OMException)e;
+      }
+      throw new OMException("Renew delegation token failed.", e,
+          TOKEN_ERROR_OTHER);
     }
   }
 
@@ -1221,11 +1242,10 @@ public long renewDelegationToken(Token<OzoneTokenIdentifier> token)
    * Cancel an existing delegation token.
    *
    * @param token delegation token
-   * @throws IOException
    */
   @Override
   public void cancelDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws IOException {
+      throws OMException {
     CancelDelegationTokenRequestProto req = CancelDelegationTokenRequestProto
         .newBuilder()
         .setToken(OMPBHelper.convertToTokenProto(token))
@@ -1235,11 +1255,40 @@ public void cancelDelegationToken(Token<OzoneTokenIdentifier> token)
         .setCancelDelegationTokenRequest(req)
         .build();
 
-    final CancelDelegationTokenResponseProto resp = submitRequest(omRequest)
-        .getCancelDelegationTokenResponse();
-    if (resp.getStatus() != Status.OK) {
-      throw new IOException("Cancel Delegation Token failed, error : " + resp
-          .getStatus());
+    final CancelDelegationTokenResponseProto resp;
+    try {
+      resp = submitRequest(omRequest).getCancelDelegationTokenResponse();
+      if (resp.getStatus() == OK) {
+        return;
+      }
+      throw new OMException("Cancel delegation token failed with response:"
+          + resp.getStatus(), toResultStatus(resp.getStatus()));
+    } catch (IOException e) {
+      if(e instanceof OMException) {
+        throw (OMException)e;
+      }
+      throw new OMException("Cancel delegation token failed.", e,
+          TOKEN_ERROR_OTHER);
+    }
+  }
+
+  /**
+   * Converts proto status to OMException result code.
+   *
+   * @param status Proto status received from rpc call.
+   */
+  public ResultCodes toResultStatus(Status status) {
+    switch (status) {
+    case INVALID_AUTH_METHOD:
+      return ResultCodes.INVALID_AUTH_METHOD;
+    case INVALID_TOKEN:
+      return ResultCodes.INVALID_TOKEN;
+    case TOKEN_EXPIRED:
+      return ResultCodes.TOKEN_EXPIRED;
+    case TOKEN_ERROR_OTHER:
+      return TOKEN_ERROR_OTHER;
+    default:
+      return UNKNOWN;
     }
   }
 }
diff --git a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
index 0b40f96de3..8c4b90be3d 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/OzoneDelegationTokenSecretManager.java
@@ -22,6 +22,7 @@
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.security.x509.SecurityConfig;
 import org.apache.hadoop.io.Text;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.security.OzoneSecretStore.OzoneManagerSecretState;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier.TokenInfo;
 import org.apache.hadoop.security.AccessControlException;
@@ -41,6 +42,8 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_EXPIRED;
+
 /**
  * SecretManager for Ozone Master. Responsible for signing identifiers with
  * private key,
@@ -172,8 +175,7 @@ private void updateIdentifierDetails(OzoneTokenIdentifier identifier) {
    */
   @Override
   public synchronized long renewToken(Token<OzoneTokenIdentifier> token,
-      String renewer)
-      throws IOException {
+      String renewer) throws IOException {
     ByteArrayInputStream buf = new ByteArrayInputStream(token.getIdentifier());
     DataInputStream in = new DataInputStream(buf);
     OzoneTokenIdentifier id = OzoneTokenIdentifier.readProtoBuf(in);
@@ -184,10 +186,10 @@ public synchronized long renewToken(Token<OzoneTokenIdentifier> token,
 
     long now = Time.monotonicNow();
     if (id.getMaxDate() < now) {
-      throw new InvalidToken(renewer + " tried to renew an expired token "
+      throw new OMException(renewer + " tried to renew an expired token "
           + formatTokenId(id) + " max expiration date: "
           + Time.formatTime(id.getMaxDate())
-          + " currentTime: " + Time.formatTime(now));
+          + " currentTime: " + Time.formatTime(now), TOKEN_EXPIRED);
     }
     validateToken(id);
     if ((id.getRenewer() == null) || (id.getRenewer().toString().isEmpty())) {
diff --git a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto
index 98958e6cc7..1889a28945 100644
--- a/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto
+++ b/hadoop-ozone/common/src/main/proto/OzoneManagerProtocol.proto
@@ -208,6 +208,12 @@ enum Status {
     ABORT_MULTIPART_UPLOAD_FAILED = 31;
 
     S3_SECRET_NOT_FOUND = 32;
+
+    INVALID_AUTH_METHOD = 33;
+    INVALID_TOKEN = 34;
+    TOKEN_EXPIRED = 35;
+    TOKEN_ERROR_OTHER = 36;
+
 }
 
 
diff --git a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
index 165b249cb2..5e3e2f6334 100644
--- a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
+++ b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/TestSecureOzoneCluster.java
@@ -21,6 +21,9 @@
 import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ADMINISTRATORS;
 import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_ENABLED;
 import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SECURITY_ENABLED_KEY;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_AUTH_METHOD;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_ERROR_OTHER;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_EXPIRED;
 import static org.slf4j.event.Level.INFO;
 
 import java.io.File;
@@ -50,7 +53,6 @@
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.ipc.Client;
 import org.apache.hadoop.ipc.RPC;
-import org.apache.hadoop.ipc.RemoteException;
 import org.apache.hadoop.ipc.Server;
 import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
 import org.apache.hadoop.minikdc.MiniKdc;
@@ -58,13 +60,13 @@
 import org.apache.hadoop.ozone.om.OMConfigKeys;
 import org.apache.hadoop.ozone.om.OMStorage;
 import org.apache.hadoop.ozone.om.OzoneManager;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolClientSideTranslatorPB;
 import org.apache.hadoop.ozone.om.protocolPB.OzoneManagerProtocolPB;
 import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
 import org.apache.hadoop.security.KerberosAuthException;
 import org.apache.hadoop.security.SaslRpcServer.AuthMethod;
 import org.apache.hadoop.security.UserGroupInformation;
-import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
 import org.apache.hadoop.security.authentication.client.AuthenticationException;
 import org.apache.hadoop.security.token.Token;
 import org.apache.hadoop.test.GenericTestUtils;
@@ -80,7 +82,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import javax.ws.rs.HEAD;
 
 /**
  * Test class to for security enabled Ozone cluster.
@@ -345,6 +346,7 @@ public void testDelegationToken() throws Exception {
 
     // Capture logs for assertions
     LogCapturer logs = LogCapturer.captureLogs(Server.AUDITLOG);
+    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
     GenericTestUtils
         .setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
 
@@ -407,18 +409,28 @@ public Void run() throws Exception {
       Assert.assertFalse(logs.getOutput().contains(
           "Auth successful for " + username + " (auth:TOKEN)"));
       LambdaTestUtils.intercept(IOException.class, "Delete Volume failed,"
-              + " error:VOLUME_NOT_FOUND", () -> omClient.deleteVolume("vol1"));
+          + " error:VOLUME_NOT_FOUND", () -> omClient.deleteVolume("vol1"));
       Assert.assertTrue(logs.getOutput().contains("Auth successful for "
           + username + " (auth:TOKEN)"));
 
       // Case 4: Test failure of token renewal.
       // Call to renewDelegationToken will fail but it will confirm that
       // initial connection via DT succeeded
-      LambdaTestUtils.intercept(RemoteException.class, "Delegation "
-              + "Token can be renewed only with kerberos or web authentication",
-          () -> omClient.renewDelegationToken(token));
+      omLogs.clearOutput();
+
+      LambdaTestUtils.intercept(OMException.class, "Renew delegation token " +
+              "failed",
+          () -> {
+            try {
+              omClient.renewDelegationToken(token);
+            } catch (OMException ex) {
+              Assert.assertTrue(ex.getResult().equals(INVALID_AUTH_METHOD));
+              throw ex;
+            }
+          });
       Assert.assertTrue(logs.getOutput().contains(
           "Auth successful for " + username + " (auth:TOKEN)"));
+      omLogs.clearOutput();
       //testUser.setAuthenticationMethod(AuthMethod.KERBEROS);
       UserGroupInformation.setLoginUser(ugi);
       omClient = new OzoneManagerProtocolClientSideTranslatorPB(
@@ -438,16 +450,25 @@ public Void run() throws Exception {
 
       // Case 6: Test failure of token cancellation.
       // Get Om client, this time authentication using Token will fail as
-      // token is expired
+      // token is not in cache anymore.
       omClient = new OzoneManagerProtocolClientSideTranslatorPB(
           RPC.getProxy(OzoneManagerProtocolPB.class, omVersion,
               OmUtils.getOmAddress(conf), testUser, conf,
               NetUtils.getDefaultSocketFactory(conf),
               Client.getRpcTimeout(conf)), RandomStringUtils.randomAscii(5));
-      LambdaTestUtils.intercept(RemoteException.class, "can't be found in cache",
-          () -> omClient.cancelDelegationToken(token));
+      LambdaTestUtils.intercept(OMException.class, "Cancel delegation " +
+              "token failed",
+          () -> {
+            try {
+              omClient.cancelDelegationToken(token);
+            } catch (OMException ex) {
+              Assert.assertTrue(ex.getResult().equals(TOKEN_ERROR_OTHER));
+              throw ex;
+            }
+          });
+
       Assert.assertTrue(logs.getOutput().contains("Auth failed for"));
-  } finally {
+    } finally {
       om.stop();
       om.join();
     }
@@ -469,6 +490,7 @@ private void generateKeyPair(OzoneConfiguration config) throws Exception {
   public void testDelegationTokenRenewal() throws Exception {
     GenericTestUtils
         .setLogLevel(LoggerFactory.getLogger(Server.class.getName()), INFO);
+    LogCapturer omLogs = LogCapturer.captureLogs(OzoneManager.getLogger());
 
     // Setup secure OM for start.
     OzoneConfiguration newConf = new OzoneConfiguration(conf);
@@ -502,16 +524,35 @@ public void testDelegationTokenRenewal() throws Exception {
       // Renew delegation token
       long expiryTime = omClient.renewDelegationToken(token);
       Assert.assertTrue(expiryTime > 0);
+      omLogs.clearOutput();
 
       // Test failure of delegation renewal
-      // 1. When renewer doesn't match (implicitly covers when renewer is
+      // 1. When token maxExpiryTime exceeds
+      Thread.sleep(500);
+      LambdaTestUtils.intercept(OMException.class,
+          "Renew delegation token failed",
+          () -> {
+            try {
+              omClient.renewDelegationToken(token);
+            } catch (OMException ex) {
+              Assert.assertTrue(ex.getResult().equals(TOKEN_EXPIRED));
+              throw ex;
+            }
+          });
+
+      omLogs.clearOutput();
+
+      // 2. When renewer doesn't match (implicitly covers when renewer is
       // null or empty )
       Token token2 = omClient.getDelegationToken(new Text("randomService"));
-      LambdaTestUtils.intercept(RemoteException.class,
-          " with non-matching renewer randomService",
+      LambdaTestUtils.intercept(OMException.class,
+          "Renew delegation token failed",
           () -> omClient.renewDelegationToken(token2));
+      Assert.assertTrue(omLogs.getOutput().contains(" with non-matching " +
+          "renewer randomService"));
+      omLogs.clearOutput();
 
-      // 2. Test tampered token
+      // 3. Test tampered token
       OzoneTokenIdentifier tokenId = OzoneTokenIdentifier.readProtoBuf(
           token.getIdentifier());
       tokenId.setRenewer(new Text("om"));
@@ -519,15 +560,13 @@ public void testDelegationTokenRenewal() throws Exception {
       Token<OzoneTokenIdentifier> tamperedToken = new Token<>(
           tokenId.getBytes(), token2.getPassword(), token2.getKind(),
           token2.getService());
-      LambdaTestUtils.intercept(RemoteException.class,
-          "can't be found in cache",
+      LambdaTestUtils.intercept(OMException.class,
+          "Renew delegation token failed",
           () -> omClient.renewDelegationToken(tamperedToken));
+      Assert.assertTrue(omLogs.getOutput().contains("can't be found in " +
+          "cache"));
+      omLogs.clearOutput();
 
-      // 3. When token maxExpiryTime exceeds
-      Thread.sleep(500);
-      LambdaTestUtils.intercept(RemoteException.class,
-          "om tried to renew an expired" + " token",
-          () -> omClient.renewDelegationToken(token));
     } finally {
       om.stop();
       om.join();
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 7abc20897e..5b2120cd22 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -100,7 +100,6 @@
 import org.apache.hadoop.ozone.security.OzoneBlockTokenSecretManager;
 import org.apache.hadoop.ozone.security.OzoneDelegationTokenSecretManager;
 import org.apache.hadoop.ozone.util.OzoneVersionInfo;
-import org.apache.hadoop.security.AccessControlException;
 import org.apache.hadoop.security.SecurityUtil;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
@@ -157,6 +156,8 @@
     .OZONE_OM_METRICS_SAVE_INTERVAL;
 import static org.apache.hadoop.ozone.om.OMConfigKeys
     .OZONE_OM_METRICS_SAVE_INTERVAL_DEFAULT;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_AUTH_METHOD;
+import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_ERROR_OTHER;
 import static org.apache.hadoop.ozone.protocol.proto
     .OzoneManagerProtocolProtos.OzoneManagerService
     .newReflectiveBlockingService;
@@ -1031,30 +1032,37 @@ private static UserGroupInformation getRemoteUser() throws IOException {
    */
   @Override
   public Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
-      throws IOException {
+      throws OMException {
     final boolean success;
     final String tokenId;
     Token<OzoneTokenIdentifier> token;
+    try {
+      if (!isAllowedDelegationTokenOp()) {
+        throw new OMException("Delegation Token can be issued only with "
+            + "kerberos or web authentication",
+            INVALID_AUTH_METHOD);
+      }
+      if (delegationTokenMgr == null || !delegationTokenMgr.isRunning()) {
+        LOG.warn("trying to get DT with no secret manager running in OM.");
+        return null;
+      }
 
-    if (!isAllowedDelegationTokenOp()) {
-      throw new IOException("Delegation Token can be issued only with "
-          + "kerberos or web authentication");
-    }
-    if (delegationTokenMgr == null || !delegationTokenMgr.isRunning()) {
-      LOG.warn("trying to get DT with no secret manager running in OM.");
-      return null;
-    }
+      UserGroupInformation ugi = getRemoteUser();
+      String user = ugi.getUserName();
+      Text owner = new Text(user);
+      Text realUser = null;
+      if (ugi.getRealUser() != null) {
+        realUser = new Text(ugi.getRealUser().getUserName());
+      }
 
-    UserGroupInformation ugi = getRemoteUser();
-    String user = ugi.getUserName();
-    Text owner = new Text(user);
-    Text realUser = null;
-    if (ugi.getRealUser() != null) {
-      realUser = new Text(ugi.getRealUser().getUserName());
+      return delegationTokenMgr.createToken(owner, renewer, realUser);
+    } catch (OMException oex) {
+      throw oex;
+    } catch (IOException ex) {
+      LOG.error("Get Delegation token failed, cause: {}", ex.getMessage());
+      throw new OMException("Get Delegation token failed.", ex,
+          TOKEN_ERROR_OTHER);
     }
-
-    token = delegationTokenMgr.createToken(owner, renewer, realUser);
-    return token;
   }
 
   /**
@@ -1066,24 +1074,31 @@ public Token<OzoneTokenIdentifier> getDelegationToken(Text renewer)
    */
   @Override
   public long renewDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws InvalidToken, IOException {
+      throws OMException {
     long expiryTime;
 
     try {
 
       if (!isAllowedDelegationTokenOp()) {
-        throw new IOException("Delegation Token can be renewed only with "
-            + "kerberos or web authentication");
+        throw new OMException("Delegation Token can be renewed only with "
+            + "kerberos or web authentication",
+            INVALID_AUTH_METHOD);
       }
       String renewer = getRemoteUser().getShortUserName();
       expiryTime = delegationTokenMgr.renewToken(token, renewer);
 
-    } catch (AccessControlException ace) {
-      final OzoneTokenIdentifier id = OzoneTokenIdentifier.readProtoBuf(
-          token.getIdentifier());
-      LOG.error("Delegation token renewal failed for dt: {}, cause: {}",
-          id.toString(), ace.getMessage());
-      throw ace;
+    } catch (OMException oex) {
+      throw oex;
+    } catch (IOException ex) {
+      OzoneTokenIdentifier id = null;
+      try {
+        id = OzoneTokenIdentifier.readProtoBuf(token.getIdentifier());
+      } catch (IOException exe) {
+      }
+      LOG.error("Delegation token renewal failed for dt id: {}, cause: {}",
+          id, ex.getMessage());
+      throw new OMException("Delegation token renewal failed for dt: " + token,
+          ex, TOKEN_ERROR_OTHER);
     }
     return expiryTime;
   }
@@ -1095,16 +1110,19 @@ public long renewDelegationToken(Token<OzoneTokenIdentifier> token)
    */
   @Override
   public void cancelDelegationToken(Token<OzoneTokenIdentifier> token)
-      throws IOException {
+      throws OMException {
     OzoneTokenIdentifier id = null;
     try {
       String canceller = getRemoteUser().getUserName();
       id = delegationTokenMgr.cancelToken(token, canceller);
-      LOG.trace("Delegation token renewed for dt: {}", id);
-    } catch (AccessControlException ace) {
-      LOG.error("Delegation token renewal failed for dt: {}, cause: {}", id,
-          ace.getMessage());
-      throw ace;
+      LOG.trace("Delegation token cancelled for dt: {}", id);
+    } catch (OMException oex) {
+      throw oex;
+    } catch (IOException ex) {
+      LOG.error("Delegation token cancellation failed for dt id: {}, cause: {}",
+          id, ex.getMessage());
+      throw new OMException("Delegation token renewal failed for dt: " + token,
+          ex, TOKEN_ERROR_OTHER);
     }
   }
   /**
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
index aff879591a..9522d76f90 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerProtocolServerSideTranslatorPB.java
@@ -57,7 +57,7 @@ public OzoneManagerProtocolServerSideTranslatorPB(
   }
 
   /**
-   * Submit requests to Ratis server for OM HA implmentation.
+   * Submit requests to Ratis server for OM HA implementation.
    * TODO: Once HA is implemented fully, we should have only one server side
    * translator for OM protocol.
    */
diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index f7a03d9c6e..53dba69bcd 100644
--- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -163,7 +163,6 @@
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetDelegationTokenResponseProto;
 import org.apache.hadoop.security.proto.SecurityProtos.RenewDelegationTokenRequestProto;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RenewDelegationTokenResponseProto;
-import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3SecretRequest;
 import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3SecretResponse;
 import org.apache.hadoop.security.token.Token;
 
@@ -418,6 +417,14 @@ private Status exceptionToResponseStatus(IOException ex) {
         return Status.ENTITY_TOO_SMALL;
       case ABORT_MULTIPART_UPLOAD_FAILED:
         return Status.ABORT_MULTIPART_UPLOAD_FAILED;
+      case INVALID_AUTH_METHOD:
+        return Status.INVALID_AUTH_METHOD;
+      case INVALID_TOKEN:
+        return Status.INVALID_TOKEN;
+      case TOKEN_EXPIRED:
+        return Status.TOKEN_EXPIRED;
+      case TOKEN_ERROR_OTHER:
+        return Status.TOKEN_ERROR_OTHER;
       default:
         return Status.INTERNAL_ERROR;
       }
@@ -963,7 +970,7 @@ private GetDelegationTokenResponseProto getDelegationToken(
                 .convertToTokenProto(token)).build());
       }
       rb.setStatus(Status.OK);
-      } catch (IOException ex) {
+    } catch (IOException ex) {
       rb.setStatus(exceptionToResponseStatus(ex));
     }
     return rb.build();