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 propertySdkBaseException.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
orretryStrategy.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
or
NoClassDefFoundError?
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 application, 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
Additionally, be aware that minor version bumps in SDK/Smithy modules might contain
breaking changes as described in the
SDK’s versioning policy
I see a NoClassDefFoundError
for
okhttp3/coroutines/ExecuteAsyncKt
If you see this error, it most likely means that you haven't configured your service client
to use the OkHttp4Engine
. Review the documentationOkHttp4Engine
in your code.