{"record":{"id":"45e4b45afce627ae","repo":"apache/seatunnel","slug":"ambiguous-timeout-on-couchbase-write-docid","errorCode":null,"errorMessage":"Ambiguous timeout on Couchbase write (docId='{}'), attempt={} — will retry from the same position to verify commit status.","messagePattern":"Ambiguous timeout on Couchbase write \\(docId='(.+?)'\\), attempt=(.+?) — will retry from the same position to verify commit status\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-couchbase/src/main/java/org/apache/seatunnel/connectors/seatunnel/couchbase/sink/CouchbaseWriter.java","lineNumber":610,"sourceCode":"                                            + \" prior ambiguous timeout at index={} — treating as\"\n                                            + \" already committed; skipping.\",\n                                    unit.docId,\n                                    i);\n                            ambiguousIndices.remove(i);\n                        }\n                    }\n                    // Advance the cursor only after the write is confirmed (or confirmed-already-\n                    // present) so that a failure on the very next row does not skip this one.\n                    startFrom = i + 1;\n                }\n                buffer.clear();\n                return;\n            } catch (AmbiguousTimeoutException ate) {\n                // Record the in-flight index so the next attempt can distinguish a\n                // \"previously committed\" DocumentExistsException from a genuine collision.\n                // Do NOT advance startFrom — the next attempt replays from the same position.\n                ambiguousIndices.add(startFrom);\n                log.warn(\n                        \"Ambiguous timeout on Couchbase write (docId='{}'), attempt={} — \"\n                                + \"will retry from the same position to verify commit status.\",\n                        units.get(startFrom).docId,\n                        attempt,\n                        ate);\n                if (attempt >= maxRetries) {\n                    throw new CouchbaseConnectorException(\n                            CouchbaseConnectorErrorCode.WRITE_RECORDS_FAILED,\n                            \"Batch write to Couchbase failed after \" + maxRetries + \" retries\",\n                            ate);\n                }\n                attempt++;\n                try {\n                    TimeUnit.MILLISECONDS.sleep(retryIntervalMs * attempt);\n                } catch (InterruptedException ie) {\n                    Thread.currentThread().interrupt();\n                    throw new CouchbaseConnectorException(\n                            CouchbaseConnectorErrorCode.WRITE_RECORDS_FAILED,","sourceCodeStart":592,"sourceCodeEnd":628,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-couchbase/src/main/java/org/apache/seatunnel/connectors/seatunnel/couchbase/sink/CouchbaseWriter.java#L592-L628","documentation":"CouchbaseWriter.doFlush detects AmbiguousTimeoutException, meaning the SDK cannot confirm whether a mutation was committed on the server. The writer records the in-flight index and replays from the same position on retry, so a DocumentExistsException on the next attempt can be interpreted as 'already committed' rather than a genuine collision. This warning is informational about a retry, not a failure — unless maxRetries is exhausted.","triggerScenarios":"A mutation (insert/upsert via docId) times out with an ambiguous outcome — the request reached the server but the ack was lost or the op was still in flight when the timeout fired.","commonSituations":"High latency or GC pauses between client and Couchbase cluster; network flaps; KV timeouts set too aggressively for workload; heavy cluster load or rebalance in progress.","solutions":["No action needed if retries succeed — the writer verifies commit status automatically; check logs for subsequent success","Increase SDK/operation timeouts or maxRetries in the sink config if ambiguity happens frequently","Investigate network stability and Couchbase cluster health (rebalances, failovers); tune bucket RAM and index settings under load"],"exampleFix":"// before (aggressive timeouts)\n.timeout(Duration.ofSeconds(2))\n// after\n.timeout(Duration.ofSeconds(10)) // tolerate latency spikes; writer still replays safely\n.maxRetries = 5;","handlingStrategy":"retry","validationCode":"// Pre-check connectivity/bucket health before writing\ncluster.bucket(bucketName).waitUntilReady(Duration.ofSeconds(10));","typeGuard":null,"tryCatchPattern":"try {\n  collection.mutateIn(docId, specs);\n} catch (AmbiguousTimeoutException e) {\n  // retry same op; treat DocumentExistsException on retry as success (already committed)\n}","preventionTips":["Set realistic KV timeouts above p99 write latency","Monitor Couchbase cluster for rebalances and overload","Keep maxRetries configured so ambiguous writes are always resolved"],"tags":["couchbase","timeout","retry","idempotency"],"backgroundTag":"request-timeout","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}