All Products
Search
Document Center

Key Management Service:Retry requests with exponential backoff

Last Updated:Aug 24, 2026

When you call KMS APIs, errors may occasionally be returned. This topic describes how to use exponential backoff to retry request errors.

Background

When you call a service API, an error may occur at a certain point. In this case, you can retry the request in your application.

Some Alibaba Cloud SDKs support automatic retries through configuration. For example, the Alibaba Cloud SDK for .NET allows you to configure retry policies. When automatic retries are not applicable, you can use the retry method described in this topic.

Retry strategies

If a request fails due to a server error (5xx) or a throttling error, retry the request by using the following retry strategies:

  • Simple retry.

    For example, retry once per second for 10 seconds.

  • Exponential backoff.

    For consecutive error responses, the retry wait interval becomes increasingly longer. You must retry based on the maximum delay interval and the maximum number of retries. Exponential backoff can prevent continuous conflicts during retries. For example, when requests exceed the throttling quota within a short period of time, exponential backoff can effectively avoid continuous throttling errors.

Important

Dedicated KMS gateways do not impose an upper limit on the number of API calls. Instead, they use a best-effort approach to maximize the use of instance compute and storage resources to process API requests. Therefore, throttling errors do not occur.

Pseudocode for exponential backoff

The following pseudocode shows how to retry an operation by using incremental delays.

initialDelay = 200
retries = 0

DO
    wait for (2^retries * initialDelay) milliseconds

    status = CallSomeAPI()

    IF status == SUCCESS
        retry = false // Succeeded, stop calling the API again.
    ELSE IF status = THROTTLED || status == SERVER_NOT_READY
        retry = true  // Failed because of throttling or server busy, try again.
    ELSE
        retry = false // Some other error occurred, stop calling the API again.
    END IF

    retries = retries + 1

WHILE (retry AND (retries < MAX_RETRIES))

Use exponential backoff to handle KMS throttling

The following Java example shows how to use exponential backoff to handle throttling errors when KMS calls the Decrypt operation.

  • You can make simple modifications to retry specific types of server errors, such as HTTP 503.

  • You can estimate the number of requests that the client sends within a specific period of time and adjust the initial delay (initialDelay) and the number of retries (maxRetries).

Note

An AccessKey pair for an Alibaba Cloud account has permissions for all API operations. We recommend that you use a RAM user to call API operations or perform routine O&M. To prevent security risks, do not hardcode your AccessKey ID and AccessKey Secret in your project code. Hardcoding credentials can lead to leaks that compromise all resources in your account.

This topic provides an example of how to configure the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables for identity authentication.

import com.aliyun.kms20160120.Client;
import com.aliyun.kms20160120.models.DecryptRequest;
import com.aliyun.kms20160120.models.DecryptResponse;
import com.aliyun.tea.*;
import com.aliyun.teautil.models.RuntimeOptions;

import java.nio.charset.StandardCharsets;

public class Main {
    private static  Client kmsClient;

    private static Client kmsClient(String regionId, String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
            .setAccessKeyId(accessKeyId)
            .setAccessKeySecret(accessKeySecret);
        config.setRegionId(regionId) ;
    return new Client(config);
    }

    private static String kmsDecrypt(String cipherTextBlob) throws Exception {
        DecryptRequest decryptRequest = new DecryptRequest()
                // Specify the ciphertext that you want to decrypt.
                .setCiphertextBlob(cipherTextBlob);
        DecryptResponse response = kmsClient.decryptWithOptions(decryptRequest, new RuntimeOptions());
        // Obtain the decrypted plaintext from the response.
        String plaintext = response.getBody().getPlaintext();

        System.out.println("Ciphertext (Base64): " + cipherTextBlob);
        System.out.println("Decrypted Plaintext: " + plaintext);
        return plaintext;
    }

    public static long getWaitTimeExponential(int retryCount) {
        final long initialDelay = 200L;
        long waitTime = ((long) Math.pow(2, retryCount) * initialDelay);
        return waitTime;
    }

    public static void main(String[] args) throws Exception {
        String regionId = "<region ID>"; // Example: "cn-shanghai"
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        String cipherTextBlob ="a2V5LXNoaDY4M**********w=";
        int maxRetries = 5;

        kmsClient =  kmsClient(regionId, accessKeyId, accessKeySecret);

        for (int i = 0; i < maxRetries; i++) {
            try {
                String plainText = kmsDecrypt(cipherTextBlob);
                return;
            } catch (Exception e) {
                e.printStackTrace();
                if (e.getMessage().contains("Rejected.Throttling")) { // Throttled. Retry the request.
                    try {
                        Thread.sleep(getWaitTimeExponential(i + 1));
                    } catch (InterruptedException ignore) {
                    }
                } else {
                    break; // Not a throttling error. Stop retrying.
                }
            }
        }
    }
}