Troubleshooting FAQs - AWS SDK for Kotlin

Troubleshooting FAQs

As you use the AWS SDK for Kotlin in your applications, you might encounter some of the issues listed in this topic. Use the following suggestions to help uncover the root cause and resolve the error.

How do I fix "connection closed" issues?

You might encounter “connection closed” issues as exceptions such as one of the following types:

  • IOException: unexpected end of stream on <URL>

  • EOFException: \n not found: limit=0

  • HttpException: AWS_ERROR_HTTP_CONNECTION_CLOSED: The connection has closed or is closing.; crtErrorCode=2058; HttpErrorCode(CONNECTION_CLOSED)

These exceptions indicate that a TCP connection from the SDK to a service was unexpectedly closed or reset. The connection might have been closed by your host, the AWS service, or an intermediary party such as a NAT gateway, proxy, or load balancer.

These types of exceptions are automatically retried but might still appear in SDK logs, depending on your logging configuration. If the exception is thrown into your code, that indicates the active retry strategy has exhausted its configured limits such as maximum attempts or retry token bucket. See the Retries section of this guide for more information about retry strategies. See also Why are exceptions thrown before reaching the maximum attempts? topic?.

Why are exceptions thrown before reaching the maximum attempts?

Sometimes you might see exceptions that you expected to be retried but were thrown instead. In these situations, the following steps might help resolve the issue.

  • Verify that the exception is retryable. Some exceptions are not retryable, such as those that indicate a malformed service request, lack of permissions, and non-existent resources, as examples. The SDK does not automatically retry these kinds of exceptions. If you’re catching an exception that inherits from SdkBaseException, you can check the boolean property SdkBaseException.sdkErrorMetadata.isRetryable to verify if the SDK has determined that the exception is retryable.

  • Verify that the exception is being thrown into your code. Some exceptions appear in log messages as information but are not actually thrown into your code. For instance, retryable exceptions such as throttling errors might be logged as the SDK automatically works through multiple backoff-and-retry cycles. The invocation of an SDK operation throws an exception only if it was not handled by the configured retry settings.

  • Verify your configured retry settings. See the Retries section of this guide for more information about retry strategies and retry policies. Ensure that your code is using the settings you expect or the automatic defaults.

  • Consider adjusting your retry settings. After you verify the previous items, but the issue is not resolved, you might consider adjusting retry settings.

    • Increase the maximum number of attempts. By default the maximum number of attempts for an operation is 3. If you find that this is not enough and exceptions are still occurring at the default setting, consider increasing the retryStrategy.maxAttempts property in your client configuration. See Maximum attempts for more information.

    • Increase the delay settings. Some exceptions might be retried too rapidly before the underlying condition has had a chance to resolve. If you suspect that do be the case, consider increasing the retryStrategy.delayProvider.initialDelay or retryStrategy.delayProvider.maxBackoff properties in your client configuration. See Delays and backofffor more information.

    • Disable circuit breaker mode. The SDK maintains a bucket of tokens for each service client by default. When the SDK attempts a request and it fails with a retryable exception, the token count is decremented; when the request succeeds the token count is incremented.

      By default, if this token bucket reaches 0 tokens remaining, the circuit is broken. After the circuit is broken, the SDK disables retries and any current and subsequent requests that fail on the first attempt immediately throw an exception. The SDK re-enables retries after successful initial attempts return enough capacity to the token bucket. This behavior is intentional and designed to prevent retry storms during service outages and service recovery.

      If you prefer that the SDK continue retrying up to the maximum configured attempts, consider disabling circuit breaker mode by setting the retryStrategy.tokenBucket.useCircuitBreakerMode property to false in your client configuration. With this property set to false, the SDK client waits until the token bucket reaches sufficient capacity rather than abandon further retries that might lead to an exception when there are 0 tokens remaining.

How do I fix NoSuchMethodError?

The SDK relies on various AWS and third-party dependencies to function correctly. If the expected dependencies are not present at runtime or are an unexpected version, you might see the NoSuchMethodError runtime exception.

Dependency conflicts usually fall into two categories: SDK/Smithy dependency conflicts and third-party dependency conflicts.

When you build a Kotlin applications, you typically manage dependencies with Gradle. Adding a dependency on an SDK service client to your application should automatically resolve and include all transitive dependencies. If your application has other dependencies, they might conflict with the dependencies needed by the SDK (for example, OkHttp is a commonly used HTTP client on which the SDK depends).

To resolve such issues, you might need to explicitly resolve a specific dependency version or shadow dependencies into a local namespace to avoid the conflict. Gradle dependency resolution is a complex topic that is discussed in the following sections of the Grade User Manual.

SDK/Smithy dependency conflicts

In general, the SDK’s modules depend on other SDK modules with the same version number. For example, aws.sdk.kotlin:s3:1.2.3 depends on aws.sdk.kotlin:aws-http:1.2.3, which depends on aws.sdk.kotlin:aws-core:1.2.3, and so on.

Additionally, SDK modules rely on specific, unified Smithy module versions as well. These Smithy version numbers are not in sync with SDK version numbers but must still match the version expected by the SDK. For example, aws.sdk.kotlin:s3:1.2.3 might depend on aws.smithy.kotlin:serde:1.1.1, which depends on aws.smithy.kotlin:runtime-core:1.1.1, and so on.

If any of these version numbers mismatch, you might encounter dependency conflicts. Ensure that you upgrade all of your SDK dependencies in unison and upgrade any explicit Smithy dependencies in unison as well. Consider using our Gradle version catalog to keep versions in sync and eliminate guesswork mapping between SDK and Smithy versions. See the Create a project file topic for more information and examples.

Additionally, be aware that minor version bumps in SDK/Smithy modules might contain breaking changes as described in the SDK’s versioning policy. When upgrading between minor versions, take extra care to examine changelogs and validate of runtime behavior thoroughly.