Repository: ratify-project/ratify
Pull request #1734 (2024-08-21 11:47:40)

feat: enhance CR status with clearer brief error message
# Description

## What this PR does / why we need it:
The PR will address the issue that brief error is too short. Basically, the brief error will just contain the error code and root cause. And if it exceeds the max length(150 charactoers), the brief error will be truncated.

1. Add a new `GetConciseError` method to custom error to create an error message consisting of the error code and reason.
2. Update all controllers to use the new `GetConciseError` method to assign brief error value.
3. Set the maxLength from 30 to 150.

Examples:
Screenshot for Policy CR:
![image](https://github.com/user-attachments/assets/fccccc2e-6d4a-45c9-8bd6-75d8b6c82f57)

![image](https://github.com/user-attachments/assets/6fac6687-b348-4069-b17a-d1e4aa9e636a)

Screenshot for Verifier CR:
![image](https://github.com/user-attachments/assets/8828f211-b5e3-4a5f-a2fc-59b5c36fb006)

![image](https://github.com/user-attachments/assets/62a9b6eb-9cd9-485d-ab5a-b9ce60360e42)

Screenshot for KMP CR:
![image](https://github.com/user-attachments/assets/512986ab-018c-4608-9d8a-13be123e02f1)

![image](https://github.com/user-attachments/assets/6b1f66ed-50a2-4856-941c-b5fa9cfc28a2)



## Which issue(s) this PR fixes *(optional, using `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when the PR gets merged)*:
Fixes https://github.com/ratify-project/ratify/issues/1453

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Helm Chart Change (any edit/addition/update that is necessary for changes merged to the `main` branch)
- [ ] This change requires a documentation update

# How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Please also list any relevant details for your test configuration

- [ ] Test A
- [ ] Test B

# Checklist:

- [ ] Does the affected code have corresponding tests?
- [ ] Are the changes documented, not just with inline documentation, but also with conceptual documentation such as an overview of a new feature, or task-based documentation like a tutorial? Consider if this change should be announced on your project blog.
- [ ] Does this introduce breaking changes that would require an announcement or bumping the major version?
- [ ] Do all new files have appropriate license header?

# Post Merge Requirements
- [ ] MAINTAINERS: manually trigger the "Publish Package" workflow after merging any PR that indicates `Helm Chart Change`


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) Report
Attention: Patch coverage is `72.72727%` with `27 lines` in your changes missing coverage. Please review.

| [Files](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) | Patch % | Lines |
|---|---|---|
| [pkg/keymanagementprovider/refresh/kubeRefresh.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fkeymanagementprovider%2Frefresh%2FkubeRefresh.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2tleW1hbmFnZW1lbnRwcm92aWRlci9yZWZyZXNoL2t1YmVSZWZyZXNoLmdv) | 60.00% | [6 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [...anagementprovider/refresh/kubeRefreshNamespaced.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fkeymanagementprovider%2Frefresh%2FkubeRefreshNamespaced.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2tleW1hbmFnZW1lbnRwcm92aWRlci9yZWZyZXNoL2t1YmVSZWZyZXNoTmFtZXNwYWNlZC5nbw==) | 60.00% | [6 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [...kg/controllers/clusterresource/store\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fclusterresource%2Fstore_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL2NsdXN0ZXJyZXNvdXJjZS9zdG9yZV9jb250cm9sbGVyLmdv) | 50.00% | [4 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [...controllers/clusterresource/verifier\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fclusterresource%2Fverifier_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL2NsdXN0ZXJyZXNvdXJjZS92ZXJpZmllcl9jb250cm9sbGVyLmdv) | 63.63% | [4 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [.../controllers/namespaceresource/store\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fnamespaceresource%2Fstore_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL25hbWVzcGFjZXJlc291cmNlL3N0b3JlX2NvbnRyb2xsZXIuZ28=) | 50.00% | [4 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |
| [...ntrollers/namespaceresource/verifier\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fnamespaceresource%2Fverifier_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL25hbWVzcGFjZXJlc291cmNlL3ZlcmlmaWVyX2NvbnRyb2xsZXIuZ28=) | 70.00% | [3 Missing :warning: ](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) |

| [Files](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project) | Coverage Δ | |
|---|---|---|
| [errors/types.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=errors%2Ftypes.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-ZXJyb3JzL3R5cGVzLmdv) | `90.90% <100.00%> (+0.43%)` | :arrow_up: |
| [...g/controllers/clusterresource/policy\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fclusterresource%2Fpolicy_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL2NsdXN0ZXJyZXNvdXJjZS9wb2xpY3lfY29udHJvbGxlci5nbw==) | `91.83% <100.00%> (-0.33%)` | :arrow_down: |
| [...controllers/namespaceresource/policy\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fnamespaceresource%2Fpolicy_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL25hbWVzcGFjZXJlc291cmNlL3BvbGljeV9jb250cm9sbGVyLmdv) | `91.83% <100.00%> (-0.33%)` | :arrow_down: |
| [...ntrollers/namespaceresource/verifier\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fnamespaceresource%2Fverifier_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL25hbWVzcGFjZXJlc291cmNlL3ZlcmlmaWVyX2NvbnRyb2xsZXIuZ28=) | `80.00% <70.00%> (ø)` | |
| [...kg/controllers/clusterresource/store\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fclusterresource%2Fstore_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL2NsdXN0ZXJyZXNvdXJjZS9zdG9yZV9jb250cm9sbGVyLmdv) | `71.79% <50.00%> (-2.57%)` | :arrow_down: |
| [...controllers/clusterresource/verifier\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fclusterresource%2Fverifier_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL2NsdXN0ZXJyZXNvdXJjZS92ZXJpZmllcl9jb250cm9sbGVyLmdv) | `78.04% <63.63%> (-1.96%)` | :arrow_down: |
| [.../controllers/namespaceresource/store\_controller.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fcontrollers%2Fnamespaceresource%2Fstore_controller.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2NvbnRyb2xsZXJzL25hbWVzcGFjZXJlc291cmNlL3N0b3JlX2NvbnRyb2xsZXIuZ28=) | `76.92% <50.00%> (+10.25%)` | :arrow_up: |
| [pkg/keymanagementprovider/refresh/kubeRefresh.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fkeymanagementprovider%2Frefresh%2FkubeRefresh.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2tleW1hbmFnZW1lbnRwcm92aWRlci9yZWZyZXNoL2t1YmVSZWZyZXNoLmdv) | `79.59% <60.00%> (-2.23%)` | :arrow_down: |
| [...anagementprovider/refresh/kubeRefreshNamespaced.go](https://app.codecov.io/gh/ratify-project/ratify/pull/1734?src=pr&el=tree&filepath=pkg%2Fkeymanagementprovider%2Frefresh%2FkubeRefreshNamespaced.go&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project#diff-cGtnL2tleW1hbmFnZW1lbnRwcm92aWRlci9yZWZyZXNoL2t1YmVSZWZyZXNoTmFtZXNwYWNlZC5nbw==) | `79.59% <60.00%> (-2.23%)` | :arrow_down: |

... and [11 files with indirect coverage changes](https://app.codecov.io/gh/ratify-project/ratify/pull/1734/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ratify-project)


Patch:
diff --git a/errors/pluginerrors.go b/errors/pluginerrors.go
index 0ec7f4c..1e44d19 100644
--- a/errors/pluginerrors.go
+++ b/errors/pluginerrors.go
@@ -168,4 +168,11 @@ var (
 		Message:     "Key vault operation failed",
 		Description: "Key vault operation failed. Please validate correct key vault configuration is provided or check the error details for further investigation.",
 	})
+
+	// ErrorCodeKeyManagementProviderFailure is returned when a key management provider operation fails.
+	ErrorCodeKeyManagementProviderFailure = Register("errcode", ErrorDescriptor{
+		Value:       "KEY_MANAGEMENT_PROVIDER_FAILURE",
+		Message:     "Key management provider failure",
+		Description: "Generic failure in key management provider. Please validate correct key management provider configuration is provided or check the error details for further investigation.",
+	})
 )
diff --git a/errors/types.go b/errors/types.go
index cb5e031..0f8f6ea 100644
--- a/errors/types.go
+++ b/errors/types.go
@@ -253,6 +253,18 @@ func (e Error) GetRemediation() string {
 	return err.remediation
 }
 
+// GetConciseError returns a formatted error message consisting of the error code and reason.
+// If the generated error message exceeds the specified maxLength, it truncates the message and appends an ellipsis ("...").
+// The function ensures that the returned error message is concise and within the length limit.
+func (e Error) GetConciseError(maxLength int) string {
+	err, _ := e.getRootError()
+	errMsg := fmt.Sprintf("%s: %s", err.ErrorCode().Descriptor().Value, e.GetErrorReason())
+	if len(errMsg) > maxLength {
+		return fmt.Sprintf("%s...", errMsg[:maxLength-3])
+	}
+	return errMsg
+}
+
 func (e Error) getRootError() (err Error, details []string) {
 	err = e
 	for !err.isRootError {
diff --git a/internal/constants/constants.go b/internal/constants/constants.go
index adda96a..0b47690 100644
--- a/internal/constants/constants.go
+++ b/internal/constants/constants.go
@@ -19,4 +19,4 @@ package constants
 const RatifyPolicy = "ratify-policy"
 const EmptyNamespace = ""
 const NamespaceSeperator = "/"
-const MaxBriefErrLength = 30
+const MaxBriefErrLength = 100
diff --git a/pkg/controllers/clusterresource/policy_controller.go b/pkg/controllers/clusterresource/policy_controller.go
index 68a62c5..f511a50 100644
--- a/pkg/controllers/clusterresource/policy_controller.go
+++ b/pkg/controllers/clusterresource/policy_controller.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/controllers/utils"
@@ -63,19 +64,20 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
 	}
 
 	if resource != constants.RatifyPolicy {
-		errStr := fmt.Sprintf("metadata.name must be ratify-policy, got %s", resource)
-		policyLogger.Error(errStr)
-		writePolicyStatus(ctx, r, &policy, policyLogger, false, errStr)
+		err := re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("metadata.name must be ratify-policy, got %s", resource))
+		policyLogger.Error(err)
+		writePolicyStatus(ctx, r, &policy, policyLogger, false, &err)
 		return ctrl.Result{}, nil
 	}
 
 	if err := policyAddOrReplace(policy.Spec); err != nil {
-		policyLogger.Error("unable to create policy from policy crd: ", err)
-		writePolicyStatus(ctx, r, &policy, policyLogger, false, err.Error())
-		return ctrl.Result{}, err
+		policyErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Unable to create policy from policy CR")
+		policyLogger.Error(policyErr)
+		writePolicyStatus(ctx, r, &policy, policyLogger, false, &policyErr)
+		return ctrl.Result{}, policyErr
 	}
 
-	writePolicyStatus(ctx, r, &policy, policyLogger, true, "")
+	writePolicyStatus(ctx, r, &policy, policyLogger, true, nil)
 	return ctrl.Result{}, nil
 }
 
@@ -89,18 +91,18 @@ func (r *PolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
 func policyAddOrReplace(spec configv1beta1.PolicySpec) error {
 	policyEnforcer, err := utils.SpecToPolicyEnforcer(spec.Parameters.Raw, spec.Type)
 	if err != nil {
-		return fmt.Errorf("failed to create policy enforcer: %w", err)
+		return err
 	}
 
 	controllers.NamespacedPolicies.AddPolicy(constants.EmptyNamespace, constants.RatifyPolicy, policyEnforcer)
 	return nil
 }
 
-func writePolicyStatus(ctx context.Context, r client.StatusClient, policy *configv1beta1.Policy, logger *logrus.Entry, isSuccess bool, errString string) {
+func writePolicyStatus(ctx context.Context, r client.StatusClient, policy *configv1beta1.Policy, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		updatePolicySuccessStatus(policy)
 	} else {
-		updatePolicyErrorStatus(policy, errString)
+		updatePolicyErrorStatus(policy, err)
 	}
 	if statusErr := r.Status().Update(ctx, policy); statusErr != nil {
 		logger.Error(statusErr, ", unable to update policy error status")
@@ -113,12 +115,8 @@ func updatePolicySuccessStatus(policy *configv1beta1.Policy) {
 	policy.Status.BriefError = ""
 }
 
-func updatePolicyErrorStatus(policy *configv1beta1.Policy, errString string) {
-	briefErr := errString
-	if len(errString) > constants.MaxBriefErrLength {
-		briefErr = fmt.Sprintf("%s...", errString[:constants.MaxBriefErrLength])
-	}
+func updatePolicyErrorStatus(policy *configv1beta1.Policy, err *re.Error) {
 	policy.Status.IsSuccess = false
-	policy.Status.Error = errString
-	policy.Status.BriefError = briefErr
+	policy.Status.Error = err.Error()
+	policy.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 }
diff --git a/pkg/controllers/clusterresource/store_controller.go b/pkg/controllers/clusterresource/store_controller.go
index 54cd91e..65342b9 100644
--- a/pkg/controllers/clusterresource/store_controller.go
+++ b/pkg/controllers/clusterresource/store_controller.go
@@ -17,7 +17,6 @@ package clusterresource
 
 import (
 	"context"
-	"fmt"
 
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -25,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/controllers/utils"
@@ -65,12 +65,13 @@ func (r *StoreReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
 	}
 
 	if err := storeAddOrReplace(store.Spec, resource); err != nil {
-		storeLogger.Error(err, "unable to create store from store crd")
-		writeStoreStatus(ctx, r, &store, storeLogger, false, err.Error())
-		return ctrl.Result{}, err
+		storeErr := re.ErrorCodeReferrerStoreFailure.WithError(err).WithDetail("Unable to create store from store CR")
+		storeLogger.Error(err)
+		writeStoreStatus(ctx, r, &store, storeLogger, false, &storeErr)
+		return ctrl.Result{}, storeErr
 	}
 
-	writeStoreStatus(ctx, r, &store, storeLogger, true, "")
+	writeStoreStatus(ctx, r, &store, storeLogger, true, nil)
 
 	// returning empty result and no error to indicate we’ve successfully reconciled this object
 	return ctrl.Result{}, nil
@@ -87,23 +88,21 @@ func (r *StoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
 func storeAddOrReplace(spec configv1beta1.StoreSpec, fullname string) error {
 	storeConfig, err := utils.CreateStoreConfig(spec.Parameters.Raw, spec.Name, spec.Source)
 	if err != nil {
-		return fmt.Errorf("unable to convert store spec to store config, err: %w", err)
+		return err
 	}
 
 	return utils.UpsertStoreMap(spec.Version, spec.Address, fullname, constants.EmptyNamespace, storeConfig)
 }
 
-func writeStoreStatus(ctx context.Context, r client.StatusClient, store *configv1beta1.Store, logger *logrus.Entry, isSuccess bool, errorString string) {
+func writeStoreStatus(ctx context.Context, r client.StatusClient, store *configv1beta1.Store, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		store.Status.IsSuccess = true
 		store.Status.Error = ""
 		store.Status.BriefError = ""
 	} else {
 		store.Status.IsSuccess = false
-		store.Status.Error = errorString
-		if len(errorString) > constants.MaxBriefErrLength {
-			store.Status.BriefError = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-		}
+		store.Status.Error = err.Error()
+		store.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	}
 
 	if statusErr := r.Status().Update(ctx, store); statusErr != nil {
diff --git a/pkg/controllers/clusterresource/verifier_controller.go b/pkg/controllers/clusterresource/verifier_controller.go
index 0eaaa60..2b72459 100644
--- a/pkg/controllers/clusterresource/verifier_controller.go
+++ b/pkg/controllers/clusterresource/verifier_controller.go
@@ -17,9 +17,9 @@ package clusterresource
 
 import (
 	"context"
-	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 
@@ -70,12 +70,13 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 	}
 
 	if err := verifierAddOrReplace(verifier.Spec, resource); err != nil {
-		verifierLogger.Error(err, "unable to create verifier from verifier crd")
-		writeVerifierStatus(ctx, r, &verifier, verifierLogger, false, err.Error())
-		return ctrl.Result{}, err
+		verifierErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Unable to create verifier from verifier CR")
+		verifierLogger.Error(verifierErr)
+		writeVerifierStatus(ctx, r, &verifier, verifierLogger, false, &verifierErr)
+		return ctrl.Result{}, verifierErr
 	}
 
-	writeVerifierStatus(ctx, r, &verifier, verifierLogger, true, "")
+	writeVerifierStatus(ctx, r, &verifier, verifierLogger, true, nil)
 
 	// returning empty result and no error to indicate we’ve successfully reconciled this object
 	return ctrl.Result{}, nil
@@ -85,8 +86,8 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string) error {
 	verifierConfig, err := cutils.SpecToVerifierConfig(spec.Parameters.Raw, objectName, spec.Name, spec.ArtifactTypes, spec.Source)
 	if err != nil {
-		logrus.Error(err, "unable to convert crd specification to verifier config")
-		return fmt.Errorf("unable to convert crd specification to verifier config, err: %w", err)
+		logrus.Error(err)
+		return err
 	}
 
 	return cutils.UpsertVerifier(spec.Version, spec.Address, constants.EmptyNamespace, objectName, verifierConfig)
@@ -99,17 +100,15 @@ func (r *VerifierReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		Complete(r)
 }
 
-func writeVerifierStatus(ctx context.Context, r client.StatusClient, verifier *configv1beta1.Verifier, logger *logrus.Entry, isSuccess bool, errorString string) {
+func writeVerifierStatus(ctx context.Context, r client.StatusClient, verifier *configv1beta1.Verifier, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		verifier.Status.IsSuccess = true
 		verifier.Status.Error = ""
 		verifier.Status.BriefError = ""
 	} else {
 		verifier.Status.IsSuccess = false
-		verifier.Status.Error = errorString
-		if len(errorString) > constants.MaxBriefErrLength {
-			verifier.Status.BriefError = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-		}
+		verifier.Status.Error = err.Error()
+		verifier.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	}
 
 	if statusErr := r.Status().Update(ctx, verifier); statusErr != nil {
diff --git a/pkg/controllers/namespaceresource/policy_controller.go b/pkg/controllers/namespaceresource/policy_controller.go
index d77e492..04417fb 100644
--- a/pkg/controllers/namespaceresource/policy_controller.go
+++ b/pkg/controllers/namespaceresource/policy_controller.go
@@ -20,6 +20,7 @@ import (
 	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/controllers/utils"
@@ -63,19 +64,20 @@ func (r *PolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
 	}
 
 	if resource != constants.RatifyPolicy {
-		errStr := fmt.Sprintf("metadata.name must be ratify-policy, got %s", resource)
-		policyLogger.Error(errStr)
-		writePolicyStatus(ctx, r, &policy, policyLogger, false, errStr)
+		err := re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("metadata.name must be ratify-policy, got %s", resource))
+		policyLogger.Error(err)
+		writePolicyStatus(ctx, r, &policy, policyLogger, false, &err)
 		return ctrl.Result{}, nil
 	}
 
 	if err := policyAddOrReplace(policy.Spec, req.Namespace); err != nil {
-		policyLogger.Error("unable to create policy from policy crd: ", err)
-		writePolicyStatus(ctx, r, &policy, policyLogger, false, err.Error())
-		return ctrl.Result{}, err
+		policyErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Unable to create policy from policy CR")
+		policyLogger.Error(policyErr)
+		writePolicyStatus(ctx, r, &policy, policyLogger, false, &policyErr)
+		return ctrl.Result{}, policyErr
 	}
 
-	writePolicyStatus(ctx, r, &policy, policyLogger, true, "")
+	writePolicyStatus(ctx, r, &policy, policyLogger, true, nil)
 	return ctrl.Result{}, nil
 }
 
@@ -89,18 +91,18 @@ func (r *PolicyReconciler) SetupWithManager(mgr ctrl.Manager) error {
 func policyAddOrReplace(spec configv1beta1.NamespacedPolicySpec, namespace string) error {
 	policyEnforcer, err := utils.SpecToPolicyEnforcer(spec.Parameters.Raw, spec.Type)
 	if err != nil {
-		return fmt.Errorf("failed to create policy enforcer: %w", err)
+		return err
 	}
 
 	controllers.NamespacedPolicies.AddPolicy(namespace, constants.RatifyPolicy, policyEnforcer)
 	return nil
 }
 
-func writePolicyStatus(ctx context.Context, r client.StatusClient, policy *configv1beta1.NamespacedPolicy, logger *logrus.Entry, isSuccess bool, errString string) {
+func writePolicyStatus(ctx context.Context, r client.StatusClient, policy *configv1beta1.NamespacedPolicy, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		updatePolicySuccessStatus(policy)
 	} else {
-		updatePolicyErrorStatus(policy, errString)
+		updatePolicyErrorStatus(policy, err)
 	}
 	if statusErr := r.Status().Update(ctx, policy); statusErr != nil {
 		logger.Error(statusErr, ", unable to update policy error status")
@@ -113,12 +115,8 @@ func updatePolicySuccessStatus(policy *configv1beta1.NamespacedPolicy) {
 	policy.Status.BriefError = ""
 }
 
-func updatePolicyErrorStatus(policy *configv1beta1.NamespacedPolicy, errString string) {
-	briefErr := errString
-	if len(errString) > constants.MaxBriefErrLength {
-		briefErr = fmt.Sprintf("%s...", errString[:constants.MaxBriefErrLength])
-	}
+func updatePolicyErrorStatus(policy *configv1beta1.NamespacedPolicy, err *re.Error) {
 	policy.Status.IsSuccess = false
-	policy.Status.Error = errString
-	policy.Status.BriefError = briefErr
+	policy.Status.Error = err.Error()
+	policy.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 }
diff --git a/pkg/controllers/namespaceresource/store_controller.go b/pkg/controllers/namespaceresource/store_controller.go
index c021a82..9c6b0f1 100644
--- a/pkg/controllers/namespaceresource/store_controller.go
+++ b/pkg/controllers/namespaceresource/store_controller.go
@@ -17,7 +17,6 @@ package namespaceresource
 
 import (
 	"context"
-	"fmt"
 
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -25,6 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/controllers/utils"
@@ -65,12 +65,13 @@ func (r *StoreReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
 	}
 
 	if err := storeAddOrReplace(store.Spec, resource, req.Namespace); err != nil {
-		storeLogger.Error(err, "unable to create store from store crd")
-		writeStoreStatus(ctx, r, &store, storeLogger, false, err.Error())
-		return ctrl.Result{}, err
+		storeErr := re.ErrorCodeReferrerStoreFailure.WithError(err).WithDetail("Unable to create store from store CR")
+		storeLogger.Error(storeErr)
+		writeStoreStatus(ctx, r, &store, storeLogger, false, &storeErr)
+		return ctrl.Result{}, storeErr
 	}
 
-	writeStoreStatus(ctx, r, &store, storeLogger, true, "")
+	writeStoreStatus(ctx, r, &store, storeLogger, true, nil)
 
 	// returning empty result and no error to indicate we’ve successfully reconciled this object
 	return ctrl.Result{}, nil
@@ -87,23 +88,21 @@ func (r *StoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
 func storeAddOrReplace(spec configv1beta1.NamespacedStoreSpec, fullname, namespace string) error {
 	storeConfig, err := utils.CreateStoreConfig(spec.Parameters.Raw, spec.Name, spec.Source)
 	if err != nil {
-		return fmt.Errorf("unable to convert store spec to store config, err: %w", err)
+		return err
 	}
 
 	return utils.UpsertStoreMap(spec.Version, spec.Address, fullname, namespace, storeConfig)
 }
 
-func writeStoreStatus(ctx context.Context, r client.StatusClient, store *configv1beta1.NamespacedStore, logger *logrus.Entry, isSuccess bool, errorString string) {
+func writeStoreStatus(ctx context.Context, r client.StatusClient, store *configv1beta1.NamespacedStore, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		store.Status.IsSuccess = true
 		store.Status.Error = ""
 		store.Status.BriefError = ""
 	} else {
 		store.Status.IsSuccess = false
-		store.Status.Error = errorString
-		if len(errorString) > constants.MaxBriefErrLength {
-			store.Status.BriefError = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-		}
+		store.Status.Error = err.Error()
+		store.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	}
 
 	if statusErr := r.Status().Update(ctx, store); statusErr != nil {
diff --git a/pkg/controllers/namespaceresource/verifier_controller.go b/pkg/controllers/namespaceresource/verifier_controller.go
index dbbd8eb..e78bd8d 100644
--- a/pkg/controllers/namespaceresource/verifier_controller.go
+++ b/pkg/controllers/namespaceresource/verifier_controller.go
@@ -17,12 +17,12 @@ package namespaceresource
 
 import (
 	"context"
-	"fmt"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 
+	re "github.com/ratify-project/ratify/errors"
 	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
 	"github.com/sirupsen/logrus"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -70,12 +70,12 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 	}
 
 	if err := verifierAddOrReplace(verifier.Spec, resource, req.Namespace); err != nil {
-		verifierLogger.Error(err, "unable to create verifier from verifier crd")
-		writeVerifierStatus(ctx, r, &verifier, verifierLogger, false, err.Error())
-		return ctrl.Result{}, err
+		verifierErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Unable to create verifier from verifier CR")
+		writeVerifierStatus(ctx, r, &verifier, verifierLogger, false, &verifierErr)
+		return ctrl.Result{}, verifierErr
 	}
 
-	writeVerifierStatus(ctx, r, &verifier, verifierLogger, true, "")
+	writeVerifierStatus(ctx, r, &verifier, verifierLogger, true, nil)
 
 	// returning empty result and no error to indicate we’ve successfully reconciled this object
 	return ctrl.Result{}, nil
@@ -85,8 +85,8 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 func verifierAddOrReplace(spec configv1beta1.NamespacedVerifierSpec, objectName string, namespace string) error {
 	verifierConfig, err := cutils.SpecToVerifierConfig(spec.Parameters.Raw, objectName, spec.Name, spec.ArtifactTypes, spec.Source)
 	if err != nil {
-		logrus.Error(err, "unable to convert crd specification to verifier config")
-		return fmt.Errorf("unable to convert crd specification to verifier config, err: %w", err)
+		logrus.Error(err)
+		return err
 	}
 
 	return cutils.UpsertVerifier(spec.Version, spec.Address, namespace, objectName, verifierConfig)
@@ -99,17 +99,15 @@ func (r *VerifierReconciler) SetupWithManager(mgr ctrl.Manager) error {
 		Complete(r)
 }
 
-func writeVerifierStatus(ctx context.Context, r client.StatusClient, verifier *configv1beta1.NamespacedVerifier, logger *logrus.Entry, isSuccess bool, errorString string) {
+func writeVerifierStatus(ctx context.Context, r client.StatusClient, verifier *configv1beta1.NamespacedVerifier, logger *logrus.Entry, isSuccess bool, err *re.Error) {
 	if isSuccess {
 		verifier.Status.IsSuccess = true
 		verifier.Status.Error = ""
 		verifier.Status.BriefError = ""
 	} else {
 		verifier.Status.IsSuccess = false
-		verifier.Status.Error = errorString
-		if len(errorString) > constants.MaxBriefErrLength {
-			verifier.Status.BriefError = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-		}
+		verifier.Status.Error = err.Error()
+		verifier.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	}
 
 	if statusErr := r.Status().Update(ctx, verifier); statusErr != nil {
diff --git a/pkg/controllers/utils/kmp.go b/pkg/controllers/utils/kmp.go
index 14f5d72..a2085cf 100644
--- a/pkg/controllers/utils/kmp.go
+++ b/pkg/controllers/utils/kmp.go
@@ -18,6 +18,7 @@ import (
 	"fmt"
 
 	c "github.com/ratify-project/ratify/config"
+	re "github.com/ratify-project/ratify/errors"
 	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/config"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/factory"
@@ -28,13 +29,13 @@ import (
 func SpecToKeyManagementProvider(raw []byte, keyManagamentSystemName string) (kmp.KeyManagementProvider, error) {
 	kmProviderConfig, err := rawToKeyManagementProviderConfig(raw, keyManagamentSystemName)
 	if err != nil {
-		return nil, fmt.Errorf("failed to parse key management provider config: %w", err)
+		return nil, err
 	}
 
 	// TODO: add Version and Address to KeyManagementProviderSpec
 	keyManagementProviderProvider, err := factory.CreateKeyManagementProviderFromConfig(kmProviderConfig, "0.1.0", c.GetDefaultPluginPath())
 	if err != nil {
-		return nil, fmt.Errorf("failed to create key management provider provider: %w", err)
+		return nil, err
 	}
 
 	return keyManagementProviderProvider, nil
@@ -48,7 +49,7 @@ func rawToKeyManagementProviderConfig(raw []byte, keyManagamentSystemName string
 		return config.KeyManagementProviderConfig{}, fmt.Errorf("no key management provider parameters provided")
 	}
 	if err := json.Unmarshal(raw, &pluginConfig); err != nil {
-		return config.KeyManagementProviderConfig{}, fmt.Errorf("unable to decode key management provider parameters.Raw: %s, err: %w", raw, err)
+		return config.KeyManagementProviderConfig{}, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("Unable to decode key management provider parameters.Raw: %s", string(raw))).WithError(err)
 	}
 
 	pluginConfig[types.Type] = keyManagamentSystemName
diff --git a/pkg/keymanagementprovider/refresh/kubeRefresh.go b/pkg/keymanagementprovider/refresh/kubeRefresh.go
index aa06118..acd967e 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefresh.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefresh.go
@@ -24,6 +24,7 @@ import (
 	"time"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
 	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
@@ -87,36 +88,41 @@ func (kr *KubeRefresher) Refresh(ctx context.Context) error {
 
 	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
 	if err != nil {
-		kmp.SetCertificateError(resource, err)
-		kmp.SetKeyError(resource, err)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		kmpErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
+
+		kmp.SetCertificateError(resource, kmpErr)
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Request = ctrl.Request{}
-		return err
+		return kmpErr
 	}
 
 	// fetch certificates and store in map
 	certificates, certAttributes, err := provider.GetCertificates(ctx)
 	if err != nil {
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch certificates from key management provider [%s] of type [%s]", resource, keyManagementProvider.Spec.Type))
+
 		kmp.SetCertificateError(resource, err)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Request = ctrl.Request{}
-		return fmt.Errorf("error fetching certificates in KMProvider %v with %v provider, error: %w", resource, keyManagementProvider.Spec.Type, err)
+		return kmpErr
 	}
 
 	// fetch keys and store in map
 	keys, keyAttributes, err := provider.GetKeys(ctx)
 	if err != nil {
-		kmp.SetKeyError(resource, err)
-		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch keys from key management provider [%s] of type [%s]", resource, keyManagementProvider.Spec.Type))
+
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Request = ctrl.Request{}
-		return fmt.Errorf("error fetching keys in KMProvider %v with %v provider, error: %w", resource, keyManagementProvider.Spec.Type, err)
+		return kmpErr
 	}
 	kmp.SaveSecrets(resource, keyManagementProvider.Spec.Type, keys, certificates)
 	// merge certificates and keys status into one
 	maps.Copy(keyAttributes, certAttributes)
 	isFetchSuccessful = true
-	emptyErrorString := ""
-	writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, emptyErrorString, lastFetchedTime, keyAttributes)
+	writeKMProviderStatus(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, nil, lastFetchedTime, keyAttributes)
 
 	logger.Infof("%v certificate(s) & %v key(s) fetched for key management provider %v", len(certificates), len(keys), resource)
 
@@ -169,11 +175,11 @@ func (kr *KubeRefresher) Create(config map[string]interface{}) (Refresher, error
 	}, nil
 }
 
-func writeKMProviderStatus(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.KeyManagementProvider, logger *logrus.Entry, isSuccess bool, errorString string, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+func writeKMProviderStatus(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.KeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
 	if isSuccess {
 		updateKMProviderSuccessStatus(keyManagementProvider, &operationTime, kmProviderStatus)
 	} else {
-		updateKMProviderErrorStatus(keyManagementProvider, errorString, &operationTime)
+		updateKMProviderErrorStatus(keyManagementProvider, err, &operationTime)
 	}
 	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
 		logger.Error(statusErr, ",unable to update key management provider error status")
@@ -181,15 +187,10 @@ func writeKMProviderStatus(ctx context.Context, r client.StatusClient, keyManage
 }
 
 // updateKMProviderErrorStatus updates the key management provider status with error, brief error and last fetched time
-func updateKMProviderErrorStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, errorString string, operationTime *metav1.Time) {
-	// truncate brief error string to maxBriefErrLength
-	briefErr := errorString
-	if len(errorString) > constants.MaxBriefErrLength {
-		briefErr = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-	}
+func updateKMProviderErrorStatus(keyManagementProvider *configv1beta1.KeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
 	keyManagementProvider.Status.IsSuccess = false
-	keyManagementProvider.Status.Error = errorString
-	keyManagementProvider.Status.BriefError = briefErr
+	keyManagementProvider.Status.Error = err.Error()
+	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	keyManagementProvider.Status.LastFetchedTime = operationTime
 }
 
diff --git a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go
index 9343250..8bd4ade 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced.go
@@ -23,6 +23,7 @@ import (
 	"time"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	cutils "github.com/ratify-project/ratify/pkg/controllers/utils"
 	kmp "github.com/ratify-project/ratify/pkg/keymanagementprovider"
@@ -86,36 +87,41 @@ func (kr *KubeRefresherNamespaced) Refresh(ctx context.Context) error {
 
 	provider, err := cutils.SpecToKeyManagementProvider(keyManagementProvider.Spec.Parameters.Raw, keyManagementProvider.Spec.Type)
 	if err != nil {
-		kmp.SetCertificateError(resource, err)
-		kmp.SetKeyError(resource, err)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		kmpErr := re.ErrorCodePluginInitFailure.WithError(err).WithDetail("Failed to create key management provider from CR")
+
+		kmp.SetCertificateError(resource, kmpErr)
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Result = ctrl.Result{}
-		return err
+		return kmpErr
 	}
 
 	// fetch certificates and store in map
 	certificates, certAttributes, err := provider.GetCertificates(ctx)
 	if err != nil {
-		kmp.SetCertificateError(resource, err)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch certificates from key management provider: %s of type: %s", resource, keyManagementProvider.Spec.Type))
+
+		kmp.SetCertificateError(resource, kmpErr)
+		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Result = ctrl.Result{}
-		return fmt.Errorf("error fetching certificates in KMProvider %v with %v provider, error: %w", resource, keyManagementProvider.Spec.Type, err)
+		return kmpErr
 	}
 
 	// fetch keys and store in map
 	keys, keyAttributes, err := provider.GetKeys(ctx)
 	if err != nil {
-		kmp.SetKeyError(resource, err)
-		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, err.Error(), lastFetchedTime, nil)
+		kmpErr := re.ErrorCodeKeyManagementProviderFailure.WithError(err).WithDetail(fmt.Sprintf("Unable to fetch keys from key management provider: %s of type: %s", resource, keyManagementProvider.Spec.Type))
+
+		kmp.SetKeyError(resource, kmpErr)
+		writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, &kmpErr, lastFetchedTime, nil)
 		kr.Result = ctrl.Result{}
-		return fmt.Errorf("error fetching keys in KMProvider %v with %v provider, error: %w", resource, keyManagementProvider.Spec.Type, err)
+		return kmpErr
 	}
 	kmp.SaveSecrets(resource, keyManagementProvider.Spec.Type, keys, certificates)
 	// merge certificates and keys status into one
 	maps.Copy(keyAttributes, certAttributes)
 	isFetchSuccessful = true
-	emptyErrorString := ""
-	writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, emptyErrorString, lastFetchedTime, keyAttributes)
+	writeKMProviderStatusNamespaced(ctx, kr, &keyManagementProvider, logger, isFetchSuccessful, nil, lastFetchedTime, keyAttributes)
 
 	logger.Infof("%v certificate(s) & %v key(s) fetched for key management provider %v", len(certificates), len(keys), resource)
 
@@ -167,11 +173,11 @@ func (kr *KubeRefresherNamespaced) Create(config map[string]interface{}) (Refres
 }
 
 // writeKMProviderStatus updates the status of the key management provider resource
-func writeKMProviderStatusNamespaced(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, logger *logrus.Entry, isSuccess bool, errorString string, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
+func writeKMProviderStatusNamespaced(ctx context.Context, r client.StatusClient, keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, logger *logrus.Entry, isSuccess bool, err *re.Error, operationTime metav1.Time, kmProviderStatus kmp.KeyManagementProviderStatus) {
 	if isSuccess {
 		updateKMProviderSuccessStatusNamespaced(keyManagementProvider, &operationTime, kmProviderStatus)
 	} else {
-		updateKMProviderErrorStatusNamespaced(keyManagementProvider, errorString, &operationTime)
+		updateKMProviderErrorStatusNamespaced(keyManagementProvider, err, &operationTime)
 	}
 	if statusErr := r.Status().Update(ctx, keyManagementProvider); statusErr != nil {
 		logger.Error(statusErr, ",unable to update key management provider error status")
@@ -179,15 +185,10 @@ func writeKMProviderStatusNamespaced(ctx context.Context, r client.StatusClient,
 }
 
 // updateKMProviderErrorStatus updates the key management provider status with error, brief error and last fetched time
-func updateKMProviderErrorStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, errorString string, operationTime *metav1.Time) {
-	// truncate brief error string to maxBriefErrLength
-	briefErr := errorString
-	if len(errorString) > constants.MaxBriefErrLength {
-		briefErr = fmt.Sprintf("%s...", errorString[:constants.MaxBriefErrLength])
-	}
+func updateKMProviderErrorStatusNamespaced(keyManagementProvider *configv1beta1.NamespacedKeyManagementProvider, err *re.Error, operationTime *metav1.Time) {
 	keyManagementProvider.Status.IsSuccess = false
-	keyManagementProvider.Status.Error = errorString
-	keyManagementProvider.Status.BriefError = briefErr
+	keyManagementProvider.Status.Error = err.Error()
+	keyManagementProvider.Status.BriefError = err.GetConciseError(constants.MaxBriefErrLength)
 	keyManagementProvider.Status.LastFetchedTime = operationTime
 }
 


Test patch:
diff --git a/errors/types_test.go b/errors/types_test.go
index a1f66e3..93a96d9 100644
--- a/errors/types_test.go
+++ b/errors/types_test.go
@@ -139,6 +139,18 @@ func TestWithDescription(t *testing.T) {
 	}
 }
 
+func TestGetConciseError(t *testing.T) {
+	err := testEC.WithDetail("long message, long message, long message")
+	if err.GetConciseError(30) != "TEST_ERROR_CODE_1: long mes..." {
+		t.Fatalf("expected: TEST_ERROR_CODE_1: long mes..., got: %s", err.GetConciseError(30))
+	}
+
+	err = testEC.WithDetail("short message")
+	if err.GetConciseError(100) != "TEST_ERROR_CODE_1: short message" {
+		t.Fatalf("expected: TEST_ERROR_CODE_1: short message, got: %s", err.GetConciseError(100))
+	}
+}
+
 func TestIs(t *testing.T) {
 	err := testEC.WithDetail(testDetail1)
 	result := err.Is(err)
diff --git a/pkg/controllers/clusterresource/policy_controller_test.go b/pkg/controllers/clusterresource/policy_controller_test.go
index 2df24f8..909c702 100644
--- a/pkg/controllers/clusterresource/policy_controller_test.go
+++ b/pkg/controllers/clusterresource/policy_controller_test.go
@@ -20,6 +20,7 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/customresources/policies"
@@ -110,7 +111,8 @@ func TestWritePolicyStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(_ *testing.T) {
-			writePolicyStatus(context.Background(), tc.reconciler, tc.policy, logger, tc.isSuccess, tc.errString)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writePolicyStatus(context.Background(), tc.reconciler, tc.policy, logger, tc.isSuccess, &err)
 		})
 	}
 }
diff --git a/pkg/controllers/clusterresource/store_controller_test.go b/pkg/controllers/clusterresource/store_controller_test.go
index 69dabca..fbd0934 100644
--- a/pkg/controllers/clusterresource/store_controller_test.go
+++ b/pkg/controllers/clusterresource/store_controller_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	rs "github.com/ratify-project/ratify/pkg/customresources/referrerstores"
@@ -120,7 +121,8 @@ func TestWriteStoreStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(_ *testing.T) {
-			writeStoreStatus(context.Background(), tc.reconciler, tc.store, logger, tc.isSuccess, tc.errString)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeStoreStatus(context.Background(), tc.reconciler, tc.store, logger, tc.isSuccess, &err)
 		})
 	}
 }
@@ -238,6 +240,21 @@ func TestStoreReconcile(t *testing.T) {
 			expectedErr:        true,
 			expectedStoreCount: 0,
 		},
+		{
+			name: "unsupported store",
+			store: &configv1beta1.Store{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: constants.EmptyNamespace,
+					Name:      storeName,
+				},
+				Spec: configv1beta1.StoreSpec{
+					Name:    "unsupported",
+					Address: dirPath,
+				},
+			},
+			expectedErr:        true,
+			expectedStoreCount: 0,
+		},
 	}
 
 	for _, tt := range tests {
diff --git a/pkg/controllers/clusterresource/verifier_controller_test.go b/pkg/controllers/clusterresource/verifier_controller_test.go
index 827f362..850a1fb 100644
--- a/pkg/controllers/clusterresource/verifier_controller_test.go
+++ b/pkg/controllers/clusterresource/verifier_controller_test.go
@@ -23,6 +23,7 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/internal/constants"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/customresources/verifiers"
@@ -189,11 +190,13 @@ func TestVerifier_UpdateAndDelete(t *testing.T) {
 func TestWriteVerifierStatus(t *testing.T) {
 	logger := logrus.WithContext(context.Background())
 	testCases := []struct {
-		name       string
-		isSuccess  bool
-		verifier   *configv1beta1.Verifier
-		errString  string
-		reconciler client.StatusClient
+		name                   string
+		isSuccess              bool
+		verifier               *configv1beta1.Verifier
+		errString              string
+		expectedErrString      string
+		expectedBriefErrString string
+		reconciler             client.StatusClient
 	}{
 		{
 			name:       "success status",
@@ -203,11 +206,13 @@ func TestWriteVerifierStatus(t *testing.T) {
 			reconciler: &mockStatusClient{},
 		},
 		{
-			name:       "error status",
-			isSuccess:  false,
-			verifier:   &configv1beta1.Verifier{},
-			errString:  "a long error string that exceeds the max length of 30 characters",
-			reconciler: &mockStatusClient{},
+			name:                   "error status",
+			isSuccess:              false,
+			verifier:               &configv1beta1.Verifier{},
+			errString:              "a long error string that exceeds the max length of 100 characters, a long error string that exceeds the max length of 100 characters",
+			expectedErrString:      "UNKNOWN: a long error string that exceeds the max length of 100 characters, a long error string that exceeds the max length of 100 characters",
+			expectedBriefErrString: "UNKNOWN: a long error string that exceeds the max length of 100 characters, a long error string t...",
+			reconciler:             &mockStatusClient{},
 		},
 		{
 			name:      "status update failed",
@@ -221,14 +226,19 @@ func TestWriteVerifierStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			writeVerifierStatus(context.Background(), tc.reconciler, tc.verifier, logger, tc.isSuccess, tc.errString)
+			ratifyErr := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeVerifierStatus(context.Background(), tc.reconciler, tc.verifier, logger, tc.isSuccess, &ratifyErr)
 
 			if tc.verifier.Status.IsSuccess != tc.isSuccess {
 				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.verifier.Status.IsSuccess)
 			}
 
-			if tc.verifier.Status.Error != tc.errString {
-				t.Fatalf("Expected Error to be %+v , actual %+v", tc.errString, tc.verifier.Status.Error)
+			if tc.verifier.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be %+v , actual %+v", tc.expectedErrString, tc.verifier.Status.Error)
+			}
+
+			if tc.verifier.Status.BriefError != tc.expectedBriefErrString {
+				t.Fatalf("Expected BriefError to be %+v , actual %+v", tc.expectedBriefErrString, tc.verifier.Status.BriefError)
 			}
 		})
 	}
@@ -278,6 +288,21 @@ func TestVerifierReconcile(t *testing.T) {
 			expectedErr:           true,
 			expectedVerifierCount: 0,
 		},
+		{
+			name: "unsupported verifier",
+			verifier: &configv1beta1.Verifier{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: "",
+					Name:      verifierName,
+				},
+				Spec: configv1beta1.VerifierSpec{
+					Name:    "unsupported",
+					Address: dirPath,
+				},
+			},
+			expectedErr:           true,
+			expectedVerifierCount: 0,
+		},
 		{
 			name: "valid spec",
 			verifier: &configv1beta1.Verifier{
diff --git a/pkg/controllers/namespaceresource/certificatestore_controller_test.go b/pkg/controllers/namespaceresource/certificatestore_controller_test.go
index a3e93fb..4e9da51 100644
--- a/pkg/controllers/namespaceresource/certificatestore_controller_test.go
+++ b/pkg/controllers/namespaceresource/certificatestore_controller_test.go
@@ -17,7 +17,6 @@ package namespaceresource
 
 import (
 	"context"
-	"fmt"
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
@@ -106,9 +105,8 @@ func TestUpdateErrorStatus(t *testing.T) {
 	if certStore.Status.Error != expectedErr {
 		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, certStore.Status.Error)
 	}
-	expectedBriedErr := fmt.Sprintf("%s...", expectedErr[:30])
-	if certStore.Status.BriefError != expectedBriedErr {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedBriedErr, certStore.Status.Error)
+	if certStore.Status.BriefError != expectedErr {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, certStore.Status.Error)
 	}
 
 	//make sure properties of last cached cert was not overridden
diff --git a/pkg/controllers/namespaceresource/policy_controller_test.go b/pkg/controllers/namespaceresource/policy_controller_test.go
index 4dc980e..abf3b8a 100644
--- a/pkg/controllers/namespaceresource/policy_controller_test.go
+++ b/pkg/controllers/namespaceresource/policy_controller_test.go
@@ -20,6 +20,7 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/customresources/policies"
 	_ "github.com/ratify-project/ratify/pkg/policyprovider/configpolicy"
@@ -138,7 +139,8 @@ func TestWritePolicyStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(_ *testing.T) {
-			writePolicyStatus(context.Background(), tc.reconciler, tc.policy, logger, tc.isSuccess, tc.errString)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writePolicyStatus(context.Background(), tc.reconciler, tc.policy, logger, tc.isSuccess, &err)
 		})
 	}
 }
diff --git a/pkg/controllers/namespaceresource/store_controller_test.go b/pkg/controllers/namespaceresource/store_controller_test.go
index 54ddeb0..08ceac2 100644
--- a/pkg/controllers/namespaceresource/store_controller_test.go
+++ b/pkg/controllers/namespaceresource/store_controller_test.go
@@ -20,12 +20,15 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/customresources/referrerstores"
 	test "github.com/ratify-project/ratify/pkg/utils"
+	"github.com/sirupsen/logrus"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 )
@@ -107,6 +110,46 @@ func TestStoreAddOrReplace_PluginNotFound(t *testing.T) {
 	}
 }
 
+func TestWriteStoreStatus(t *testing.T) {
+	logger := logrus.WithContext(context.Background())
+	testCases := []struct {
+		name       string
+		isSuccess  bool
+		store      *configv1beta1.NamespacedStore
+		errString  string
+		reconciler client.StatusClient
+	}{
+		{
+			name:       "success status",
+			isSuccess:  true,
+			store:      &configv1beta1.NamespacedStore{},
+			reconciler: &test.MockStatusClient{},
+		},
+		{
+			name:       "error status",
+			isSuccess:  false,
+			store:      &configv1beta1.NamespacedStore{},
+			errString:  "a long error string that exceeds the max length of 30 characters",
+			reconciler: &test.MockStatusClient{},
+		},
+		{
+			name:      "status update failed",
+			isSuccess: true,
+			store:     &configv1beta1.NamespacedStore{},
+			reconciler: &test.MockStatusClient{
+				UpdateFailed: true,
+			},
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.name, func(_ *testing.T) {
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeStoreStatus(context.Background(), tc.reconciler, tc.store, logger, tc.isSuccess, &err)
+		})
+	}
+}
+
 func TestStore_UpdateAndDelete(t *testing.T) {
 	resetStoreMap()
 	dirPath, err := test.CreatePlugin(sampleName)
@@ -208,6 +251,21 @@ func TestStoreReconcile(t *testing.T) {
 			expectedErr:        true,
 			expectedStoreCount: 0,
 		},
+		{
+			name: "unsupported store",
+			store: &configv1beta1.NamespacedStore{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: testNamespace,
+					Name:      storeName,
+				},
+				Spec: configv1beta1.NamespacedStoreSpec{
+					Name:    "unsupported",
+					Address: dirPath,
+				},
+			},
+			expectedErr:        true,
+			expectedStoreCount: 0,
+		},
 	}
 
 	for _, tt := range tests {
diff --git a/pkg/controllers/namespaceresource/verifier_controller_test.go b/pkg/controllers/namespaceresource/verifier_controller_test.go
index c276a9e..ac433a5 100644
--- a/pkg/controllers/namespaceresource/verifier_controller_test.go
+++ b/pkg/controllers/namespaceresource/verifier_controller_test.go
@@ -23,6 +23,7 @@ import (
 	"testing"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/controllers"
 	"github.com/ratify-project/ratify/pkg/customresources/verifiers"
 	"github.com/ratify-project/ratify/pkg/utils"
@@ -191,11 +192,13 @@ func TestVerifier_UpdateAndDelete(t *testing.T) {
 func TestWriteVerifierStatus(t *testing.T) {
 	logger := logrus.WithContext(context.Background())
 	testCases := []struct {
-		name       string
-		isSuccess  bool
-		verifier   *configv1beta1.NamespacedVerifier
-		errString  string
-		reconciler client.StatusClient
+		name                   string
+		isSuccess              bool
+		verifier               *configv1beta1.NamespacedVerifier
+		errString              string
+		expectedErrString      string
+		expectedBriefErrString string
+		reconciler             client.StatusClient
 	}{
 		{
 			name:       "success status",
@@ -205,11 +208,13 @@ func TestWriteVerifierStatus(t *testing.T) {
 			reconciler: &mockStatusClient{},
 		},
 		{
-			name:       "error status",
-			isSuccess:  false,
-			verifier:   &configv1beta1.NamespacedVerifier{},
-			errString:  "a long error string that exceeds the max length of 30 characters",
-			reconciler: &mockStatusClient{},
+			name:                   "error status",
+			isSuccess:              false,
+			verifier:               &configv1beta1.NamespacedVerifier{},
+			errString:              "a long error string that exceeds the max length of 100 characters, a long error string that exceeds the max length of 100 characters",
+			expectedErrString:      "UNKNOWN: a long error string that exceeds the max length of 100 characters, a long error string that exceeds the max length of 100 characters",
+			expectedBriefErrString: "UNKNOWN: a long error string that exceeds the max length of 100 characters, a long error string t...",
+			reconciler:             &mockStatusClient{},
 		},
 		{
 			name:      "status update failed",
@@ -223,14 +228,19 @@ func TestWriteVerifierStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			writeVerifierStatus(context.Background(), tc.reconciler, tc.verifier, logger, tc.isSuccess, tc.errString)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeVerifierStatus(context.Background(), tc.reconciler, tc.verifier, logger, tc.isSuccess, &err)
 
 			if tc.verifier.Status.IsSuccess != tc.isSuccess {
 				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.verifier.Status.IsSuccess)
 			}
 
-			if tc.verifier.Status.Error != tc.errString {
-				t.Fatalf("Expected Error to be %+v , actual %+v", tc.errString, tc.verifier.Status.Error)
+			if tc.verifier.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be %+v , actual %+v", tc.expectedErrString, tc.verifier.Status.Error)
+			}
+
+			if tc.verifier.Status.BriefError != tc.expectedBriefErrString {
+				t.Fatalf("Expected BriefError to be %+v , actual %+v", tc.expectedBriefErrString, tc.verifier.Status.BriefError)
 			}
 		})
 	}
@@ -280,6 +290,21 @@ func TestVerifierReconcile(t *testing.T) {
 			expectedErr:           true,
 			expectedVerifierCount: 0,
 		},
+		{
+			name: "unsupported verifier",
+			verifier: &configv1beta1.NamespacedVerifier{
+				ObjectMeta: metav1.ObjectMeta{
+					Namespace: testNamespace,
+					Name:      verifierName,
+				},
+				Spec: configv1beta1.NamespacedVerifierSpec{
+					Name:    "unsupported",
+					Address: dirPath,
+				},
+			},
+			expectedErr:           true,
+			expectedVerifierCount: 0,
+		},
 		{
 			name: "valid spec",
 			verifier: &configv1beta1.NamespacedVerifier{
diff --git a/pkg/keymanagementprovider/refresh/kubeRefreshNamedspaced_test.go b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go
similarity index 89%
rename from pkg/keymanagementprovider/refresh/kubeRefreshNamedspaced_test.go
rename to pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go
index 884d94f..944f548 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefreshNamedspaced_test.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefreshNamespaced_test.go
@@ -17,12 +17,12 @@ package refresh
 
 import (
 	"context"
-	"fmt"
 	"reflect"
 	"testing"
 	"time"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
 	test "github.com/ratify-project/ratify/pkg/utils"
@@ -244,20 +244,19 @@ func TestKMProviderUpdateErrorStatusNamespaced(t *testing.T) {
 	keyManagementProvider := configv1beta1.NamespacedKeyManagementProvider{
 		Status: status,
 	}
-	expectedErr := "it's a long error from unit test"
+	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
 	lastFetchedTime := metav1.Now()
-	updateKMProviderErrorStatusNamespaced(&keyManagementProvider, expectedErr, &lastFetchedTime)
+	updateKMProviderErrorStatusNamespaced(&keyManagementProvider, &expectedErr, &lastFetchedTime)
 
 	if keyManagementProvider.Status.IsSuccess != false {
 		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
 	}
 
-	if keyManagementProvider.Status.Error != expectedErr {
+	if keyManagementProvider.Status.Error != expectedErr.Error() {
 		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
 	}
-	expectedBriedErr := fmt.Sprintf("%s...", expectedErr[:30])
-	if keyManagementProvider.Status.BriefError != expectedBriedErr {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedBriedErr, keyManagementProvider.Status.Error)
+	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
 	}
 
 	//make sure properties of last cached cert was not overridden
@@ -330,11 +329,12 @@ func TestWriteKMProviderStatusNamespaced(t *testing.T) {
 	logger := logrus.WithContext(context.Background())
 	lastFetchedTime := metav1.Now()
 	testCases := []struct {
-		name       string
-		isSuccess  bool
-		kmProvider *configv1beta1.NamespacedKeyManagementProvider
-		errString  string
-		reconciler client.StatusClient
+		name              string
+		isSuccess         bool
+		kmProvider        *configv1beta1.NamespacedKeyManagementProvider
+		errString         string
+		expectedErrString string
+		reconciler        client.StatusClient
 	}{
 		{
 			name:       "success status",
@@ -344,11 +344,12 @@ func TestWriteKMProviderStatusNamespaced(t *testing.T) {
 			reconciler: &test.MockStatusClient{},
 		},
 		{
-			name:       "error status",
-			isSuccess:  false,
-			kmProvider: &configv1beta1.NamespacedKeyManagementProvider{},
-			errString:  "a long error string that exceeds the max length of 30 characters",
-			reconciler: &test.MockStatusClient{},
+			name:              "error status",
+			isSuccess:         false,
+			kmProvider:        &configv1beta1.NamespacedKeyManagementProvider{},
+			errString:         "a long error string that exceeds the max length of 30 characters",
+			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 30 characters",
+			reconciler:        &test.MockStatusClient{},
 		},
 		{
 			name:       "status update failed",
@@ -362,14 +363,15 @@ func TestWriteKMProviderStatusNamespaced(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			writeKMProviderStatusNamespaced(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, tc.errString, lastFetchedTime, nil)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeKMProviderStatusNamespaced(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
 
 			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
 				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
 			}
 
-			if tc.kmProvider.Status.Error != tc.errString {
-				t.Fatalf("Expected Error to be %+v , actual %+v", tc.errString, tc.kmProvider.Status.Error)
+			if tc.kmProvider.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be %+v , actual %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
 			}
 		})
 	}
diff --git a/pkg/keymanagementprovider/refresh/kubeRefresh_test.go b/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
index beb5037..29319ab 100644
--- a/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
+++ b/pkg/keymanagementprovider/refresh/kubeRefresh_test.go
@@ -18,12 +18,12 @@ package refresh
 
 import (
 	"context"
-	"fmt"
 	"reflect"
 	"testing"
 	"time"
 
 	configv1beta1 "github.com/ratify-project/ratify/api/v1beta1"
+	re "github.com/ratify-project/ratify/errors"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider"
 	_ "github.com/ratify-project/ratify/pkg/keymanagementprovider/inline"
 	"github.com/ratify-project/ratify/pkg/keymanagementprovider/mocks"
@@ -246,20 +246,19 @@ func TestKMProviderUpdateErrorStatus(t *testing.T) {
 	keyManagementProvider := configv1beta1.KeyManagementProvider{
 		Status: status,
 	}
-	expectedErr := "it's a long error from unit test"
+	expectedErr := re.ErrorCodeUnknown.WithDetail("it's a long error from unit test")
 	lastFetchedTime := metav1.Now()
-	updateKMProviderErrorStatus(&keyManagementProvider, expectedErr, &lastFetchedTime)
+	updateKMProviderErrorStatus(&keyManagementProvider, &expectedErr, &lastFetchedTime)
 
 	if keyManagementProvider.Status.IsSuccess != false {
 		t.Fatalf("Unexpected error, expected isSuccess to be false , actual %+v", keyManagementProvider.Status.IsSuccess)
 	}
 
-	if keyManagementProvider.Status.Error != expectedErr {
+	if keyManagementProvider.Status.Error != expectedErr.Error() {
 		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr, keyManagementProvider.Status.Error)
 	}
-	expectedBriedErr := fmt.Sprintf("%s...", expectedErr[:30])
-	if keyManagementProvider.Status.BriefError != expectedBriedErr {
-		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedBriedErr, keyManagementProvider.Status.Error)
+	if keyManagementProvider.Status.BriefError != expectedErr.GetConciseError(150) {
+		t.Fatalf("Unexpected error string, expected %+v, got %+v", expectedErr.GetConciseError(150), keyManagementProvider.Status.Error)
 	}
 
 	//make sure properties of last cached cert was not overridden
@@ -334,11 +333,12 @@ func TestWriteKMProviderStatus(t *testing.T) {
 	logger := logrus.WithContext(context.Background())
 	lastFetchedTime := metav1.Now()
 	testCases := []struct {
-		name       string
-		isSuccess  bool
-		kmProvider *configv1beta1.KeyManagementProvider
-		errString  string
-		reconciler client.StatusClient
+		name              string
+		isSuccess         bool
+		kmProvider        *configv1beta1.KeyManagementProvider
+		errString         string
+		expectedErrString string
+		reconciler        client.StatusClient
 	}{
 		{
 			name:       "success status",
@@ -348,11 +348,12 @@ func TestWriteKMProviderStatus(t *testing.T) {
 			reconciler: &test.MockStatusClient{},
 		},
 		{
-			name:       "error status",
-			isSuccess:  false,
-			kmProvider: &configv1beta1.KeyManagementProvider{},
-			errString:  "a long error string that exceeds the max length of 30 characters",
-			reconciler: &test.MockStatusClient{},
+			name:              "error status",
+			isSuccess:         false,
+			kmProvider:        &configv1beta1.KeyManagementProvider{},
+			errString:         "a long error string that exceeds the max length of 150 characters",
+			expectedErrString: "UNKNOWN: a long error string that exceeds the max length of 150 characters",
+			reconciler:        &test.MockStatusClient{},
 		},
 		{
 			name:       "status update failed",
@@ -366,14 +367,15 @@ func TestWriteKMProviderStatus(t *testing.T) {
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			writeKMProviderStatus(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, tc.errString, lastFetchedTime, nil)
+			err := re.ErrorCodeUnknown.WithDetail(tc.errString)
+			writeKMProviderStatus(context.Background(), tc.reconciler, tc.kmProvider, logger, tc.isSuccess, &err, lastFetchedTime, nil)
 
 			if tc.kmProvider.Status.IsSuccess != tc.isSuccess {
-				t.Fatalf("Expected isSuccess to be %+v , actual %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
+				t.Fatalf("Expected isSuccess to be: %+v, actual: %+v", tc.isSuccess, tc.kmProvider.Status.IsSuccess)
 			}
 
-			if tc.kmProvider.Status.Error != tc.errString {
-				t.Fatalf("Expected Error to be %+v , actual %+v", tc.errString, tc.kmProvider.Status.Error)
+			if tc.kmProvider.Status.Error != tc.expectedErrString {
+				t.Fatalf("Expected Error to be: %+v, actual: %+v", tc.expectedErrString, tc.kmProvider.Status.Error)
 			}
 		})
 	}