I have a Java application that interacts with Couchbase for reading and writing data. To establish a connection, I use below code. When valid connection details (host, port, username, and password) are provided, the connection is established successfully.
When invalid connection credentials (such as incorrect host, username, or password) are passed, the application encounters multiple instances of AuthenticationFailureException (accompanied by SaslAuthenticationFailedEvent) before eventually throwing an UnambiguousTimeoutException.
Despite explicitly catching AuthenticationFailureException, it is not being handled properly in the current implementation. Instead, the logs are flooded with repeated connection attempts and authentication failure messages before the final timeout.
waitUntilReady doesn’t throw AuthenticationFailureException. Only timeout, if it cannot establish the desired connectivity within the timeout.
The SDK will retry forever - if the credentials are eventually set to what the SDK expects, then operations will start working. Note that the SDK will attempt to connect to the cluster asynchronously from the couchbase operations (get(), replace() etc). So even when an operation is not being made, the SDK will continuously try to connect.
Is there a way to disable multiple retry?
While FailFastRetryStrategy (or a custom RetryStrategy) could be used, I don’t think it will help for waitUntilReady().
FastFailRetryStrategy will disable multiple retries for every type of failure on an operation. You can also create and supply your own retry strategy and have special handling for the bad password case - SDK Release Notes | Couchbase Docs. However - I don’t think this will stop the SDK from trying to establish a connection with the cluster. I think it will just result in the operation failing on the first try - instead of retrying until timeout.
Thank you for the response.
Here are my follow-up questions:
If I switch to the recommended approach of creating a connection using Cluster.connect(connectionString, ClusterOptions), will I still encounter the same AuthenticationFailureException and multiple retry attempts when invalid credentials are provided?
I’ve used FailFastRetryStrategy, but it didn’t seem to help. From my understanding, the RetryStrategy primarily applies to data operations like get, insert, or replace, and not to authentication failures. Is that correct?
If I switch to the recommended approach of creating a connection using
Same thing.
I’ve used FailFastRetryStrategy , but it didn’t seem to help. From my understanding, the RetryStrategy primarily applies to data operations like get , insert , or replace
That’s what I was trying to say…
FastFailRetryStrategy will disable multiple retries for every type of failure on an operation.
However - I don’t think this will stop the SDK from trying to establish a connection with the cluster. I think it will just result in the operation failing
Is this a normal situation for your application? To use invalid credentials? Wouldn’t an application normally use the correct credentials?
If you want your application to fail faster, you could specify a shorter timeout for waitUntilReady().
Thank you for you quick response.
This isn’t a typical scenario; I accidentally passed invalid credentials, which caused my application server to be flooded with AuthenticationFailureException logs. I’m trying to handle such cases more gracefully, so that when incorrect credentials are provided, a clear and immediate error is returned instead of repeated retry attempts and excessive logging.
There is no mechanism to limit the frequency of the messages.
Connecting is retried because it is possible that the SDK has the correct credentials, but the cluster has the wrong credentials, and resolution would be to update the cluster with the correct credentials at which point the SDK would be able to connect. I understand that scenario is a bit far-fetched. But it’s the same logic used in case of a network outage or temporary overload or any other type of problem. And since operations have typically a short (2.5 second by default) timeout, the retry time is short (maxes out at 0.5 seconds).
Ah, I missed that.
If you stick a breakpoint or logging in your copy of the custom RetryStrategy, it should show what’s going on.
What’s expected to happen: when you hit authentication problems the handler should get called with a RetryReason.AUTHENTICATION_ERROR, which it then raises a AuthenticationFailureException for. That should cause the operation (which I believe includes bucket.waitUntilReady(), though tbh I’m not certain) to fail with AuthenticationFailureException.
If it’s not causing waitUntilReady() to fail then you can skip that and do an operation like a KV upsert or similar - that should definitely fail.