diff --git a/deploy/chart/templates/deployment.yaml b/deploy/chart/templates/deployment.yaml
index f8877d107c9d9c3926bf7a369f71a69197f29c5f..070781ea3fb1fb0257003f2fcf1dd2922bae4214 100644
--- a/deploy/chart/templates/deployment.yaml
+++ b/deploy/chart/templates/deployment.yaml
@@ -51,6 +51,14 @@ spec:
             - --worker-threads
             - {{ .Values.workerThreads }}
           {{- end }}
+          {{- if .Values.provisioningRetryCount }}
+            - --provisioning-retry-count
+            - {{ .Values.provisioningRetryCount }}
+          {{- end }}
+          {{- if .Values.deletionRetryCount }}
+            - --deletion-retry-count
+            - {{ .Values.deletionRetryCount }}
+          {{- end }}
           volumeMounts:
             - name: config-volume
               mountPath: /etc/config/
diff --git a/deploy/chart/values.yaml b/deploy/chart/values.yaml
index 291290537559ce6542017c3b43657de589783cc5..c43a7444bea23cda2b856812aa3e581de80adb37 100644
--- a/deploy/chart/values.yaml
+++ b/deploy/chart/values.yaml
@@ -140,4 +140,10 @@ configmap:
         imagePullPolicy: IfNotPresent
 
 # Number of provisioner worker threads to call provision/delete simultaneously.
-workerThreads: 4
+# workerThreads: 4
+
+# Number of retries of failed volume provisioning. 0 means retry indefinitely.
+# provisioningRetryCount: 15
+
+# Number of retries of failed volume deletion. 0 means retry indefinitely.
+# deletionRetryCount: 15
diff --git a/main.go b/main.go
index 706b00645859ad8c791fec0cf3fdc73eb892e331..be9754ae973831ca3b4102117c79a669a74dffae 100644
--- a/main.go
+++ b/main.go
@@ -19,28 +19,32 @@ import (
 )
 
 var (
-	VERSION                = "0.0.1"
-	FlagConfigFile         = "config"
-	FlagProvisionerName    = "provisioner-name"
-	EnvProvisionerName     = "PROVISIONER_NAME"
-	DefaultProvisionerName = "rancher.io/local-path"
-	FlagNamespace          = "namespace"
-	EnvNamespace           = "POD_NAMESPACE"
-	DefaultNamespace       = "local-path-storage"
-	FlagHelperImage        = "helper-image"
-	EnvHelperImage         = "HELPER_IMAGE"
-	DefaultHelperImage     = "rancher/library-busybox:1.32.1"
-	FlagServiceAccountName = "service-account-name"
-	DefaultServiceAccount  = "local-path-provisioner-service-account"
-	EnvServiceAccountName  = "SERVICE_ACCOUNT_NAME"
-	FlagKubeconfig         = "kubeconfig"
-	DefaultConfigFileKey   = "config.json"
-	DefaultConfigMapName   = "local-path-config"
-	FlagConfigMapName      = "configmap-name"
-	FlagHelperPodFile      = "helper-pod-file"
-	DefaultHelperPodFile   = "helperPod.yaml"
-	FlagWorkerThreads      = "worker-threads"
-	DefaultWorkerThreads   = 4
+	VERSION                       = "0.0.1"
+	FlagConfigFile                = "config"
+	FlagProvisionerName           = "provisioner-name"
+	EnvProvisionerName            = "PROVISIONER_NAME"
+	DefaultProvisionerName        = "rancher.io/local-path"
+	FlagNamespace                 = "namespace"
+	EnvNamespace                  = "POD_NAMESPACE"
+	DefaultNamespace              = "local-path-storage"
+	FlagHelperImage               = "helper-image"
+	EnvHelperImage                = "HELPER_IMAGE"
+	DefaultHelperImage            = "rancher/library-busybox:1.32.1"
+	FlagServiceAccountName        = "service-account-name"
+	DefaultServiceAccount         = "local-path-provisioner-service-account"
+	EnvServiceAccountName         = "SERVICE_ACCOUNT_NAME"
+	FlagKubeconfig                = "kubeconfig"
+	DefaultConfigFileKey          = "config.json"
+	DefaultConfigMapName          = "local-path-config"
+	FlagConfigMapName             = "configmap-name"
+	FlagHelperPodFile             = "helper-pod-file"
+	DefaultHelperPodFile          = "helperPod.yaml"
+	FlagWorkerThreads             = "worker-threads"
+	DefaultWorkerThreads          = pvController.DefaultThreadiness
+	FlagProvisioningRetryCount    = "provisioning-retry-count"
+	DefaultProvisioningRetryCount = pvController.DefaultFailedProvisionThreshold
+	FlagDeletionRetryCount        = "deletion-retry-count"
+	DefaultDeletionRetryCount     = pvController.DefaultFailedDeleteThreshold
 )
 
 func cmdNotFound(c *cli.Context, command string) {
@@ -114,6 +118,16 @@ func StartCmd() cli.Command {
 				Usage: "Number of provisioner worker threads.",
 				Value: DefaultWorkerThreads,
 			},
+			cli.IntFlag{
+				Name:  FlagProvisioningRetryCount,
+				Usage: "Number of retries of failed volume provisioning. 0 means retry indefinitely.",
+				Value: DefaultProvisioningRetryCount,
+			},
+			cli.IntFlag{
+				Name:  FlagDeletionRetryCount,
+				Usage: "Number of retries of failed volume deletion. 0 means retry indefinitely.",
+				Value: DefaultDeletionRetryCount,
+			},
 		},
 		Action: func(c *cli.Context) {
 			if err := startDaemon(c); err != nil {
@@ -239,8 +253,8 @@ func startDaemon(c *cli.Context) error {
 		provisioner,
 		serverVersion.GitVersion,
 		pvController.LeaderElection(false),
-		pvController.FailedProvisionThreshold(0),
-		pvController.FailedDeleteThreshold(0),
+		pvController.FailedProvisionThreshold(c.Int(FlagProvisioningRetryCount)),
+		pvController.FailedDeleteThreshold(c.Int(FlagDeletionRetryCount)),
 		pvController.Threadiness(c.Int(FlagWorkerThreads)),
 	)
 	logrus.Debug("Provisioner started")