{"record":{"id":"11b907860b1cde99","repo":"apache/iceberg","slug":"fail-to-acquire-lock-s-by-s-interrupted-during","errorCode":null,"errorMessage":"Fail to acquire lock %s by %s, interrupted during sleep","messagePattern":"Fail to acquire lock (.+?) by (.+?), interrupted during sleep","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"warning","filePath":"aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbLockManager.java","lineNumber":217,"sourceCode":"                .tableName(lockTableName)\n                .consistentRead(true)\n                .key(toKey(entityId))\n                .build());\n\n    if (!response.hasItem()) {\n      dynamo.putItem(\n          PutItemRequest.builder()\n              .tableName(lockTableName)\n              .item(toNewItem(entityId, ownerId, heartbeatTimeoutMs()))\n              .conditionExpression(CONDITION_LOCK_ENTITY_NOT_EXIST)\n              .build());\n    } else {\n      Map<String, AttributeValue> currentItem = response.item();\n\n      try {\n        Thread.sleep(Long.parseLong(currentItem.get(COL_LEASE_DURATION_MS).n()));\n      } catch (InterruptedException e) {\n        throw new IllegalStateException(\n            String.format(\n                \"Fail to acquire lock %s by %s, interrupted during sleep\", entityId, ownerId),\n            e);\n      }\n\n      dynamo.putItem(\n          PutItemRequest.builder()\n              .tableName(lockTableName)\n              .item(toNewItem(entityId, ownerId, heartbeatTimeoutMs()))\n              .conditionExpression(CONDITION_LOCK_ENTITY_NOT_EXIST_OR_VERSION_MATCH)\n              .expressionAttributeValues(\n                  ImmutableMap.of(\n                      \":eid\", AttributeValue.builder().s(entityId).build(),\n                      \":vid\", AttributeValue.builder().s(currentItem.get(COL_VERSION).s()).build()))\n              .build());\n    }\n\n    startNewHeartbeat(entityId, ownerId);","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbLockManager.java#L199-L235","documentation":"IllegalStateException from DynamoDbLockManager.acquireOnce when the worker thread is interrupted while sleeping for the current lease duration before retrying the lock acquisition. The InterruptedException is chained as the cause. This prevents silently swallowing interruption signals during the bounded-retry acquire loop.","triggerScenarios":"acquireOnce loses the conditional put, reads the winner's lease-duration-ms and sleeps, and the thread is interrupted during Thread.sleep.","commonSituations":"Executor shutdown during task cancellation; application shutdown while a compaction/commit is waiting for a lock; test framework interrupting hung workers.","solutions":["Let the exception propagate — treat interruption as a signal to stop lock acquisition","If intentional, shut down/stop the job or executor that interrupted the worker before re-running","Restore the interrupt flag if catching higher up (catch IllegalStateException, re-interrupt or abort)"],"exampleFix":"// before\ntry {\n  future.get();\n} catch (Exception e) {\n  e.printStackTrace();\n}\n// after\ntry {\n  future.get();\n} catch (java.util.concurrent.ExecutionException e) {\n  if (e.getCause() instanceof IllegalStateException\n      && e.getCause().getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt(); // honor the interruption\n  }\n  throw new RuntimeException(\"Lock acquisition aborted\", e);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  lockManager.acquire(entityId, ownerId);\n} catch (IllegalStateException e) {\n  if (e.getCause() instanceof InterruptedException) {\n    Thread.currentThread().interrupt(); // restore interrupt status\n    throw e; // honor shutdown\n  }\n  throw e;\n}","preventionTips":["Keep the worker thread's interrupt status in mind — treat it as a stop signal","Avoid interrupting threads that hold or wait for locks during graceful shutdown","Use timeouts and orderly cancellation instead of Thread.interrupt where possible"],"tags":["aws","dynamodb","locking","thread-interrupted"],"backgroundTag":"thread-interrupted","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}