{"record":{"id":"0375bf90756de16c","repo":"GoogleContainerTools/jib","slug":"unable-to-release-lock","errorCode":null,"errorMessage":"Unable to release lock","messagePattern":"Unable to release lock","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/filesystem/LockFile.java","lineNumber":86,"sourceCode":"      fileLock = outputStream.getChannel().lock();\n      return new LockFile(lockFile, fileLock, outputStream);\n\n    } finally {\n      if (fileLock == null) {\n        outputStream.close();\n      }\n    }\n  }\n\n  /** Releases the lock file. */\n  @Override\n  public void close() {\n    try {\n      fileLock.release();\n      outputStream.close();\n\n    } catch (IOException ex) {\n      throw new IllegalStateException(\"Unable to release lock\", ex);\n\n    } finally {\n      Preconditions.checkNotNull(lockMap.get(lockFilePath)).unlock();\n    }\n  }\n}\n","sourceCodeStart":68,"sourceCodeEnd":93,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/filesystem/LockFile.java#L68-L93","documentation":"Thrown when releasing the FileLock or closing the underlying FileOutputStream in LockFile.close() fails with an IOException. The in-JVM ReentrantLock is still unlocked in a finally block, but the IllegalStateException signals something abnormal with the filesystem. Since close() overrides AutoCloseable.close, it escapes the try-with-resources block unchecked.","triggerScenarios":"Closing a LockFile whose FileLock.release() or outputStream.close() throws — typically because the file channel/descriptor is already closed or the OS reports an I/O error on the lock file.","commonSituations":"Double-closing a lock file, deleting the lock file from another process while held, disk I/O errors, filesystem unmounted, or OS-level file handle exhaustion.","solutions":["Ensure each LockFile is closed exactly once (one try-with-resources scope)","Do not delete or tamper with lock files under the Jib cache directory while a build runs","Check disk health and filesystem mounts","Catch IllegalStateException around the Jib operation and inspect the cause"],"exampleFix":"// before\nLockFile lock = new LockFile(path);\nlock.close();\nlock.close(); // double close -> IllegalStateException\n// after\ntry (LockFile lock = new LockFile(path)) {\n  // critical section\n} // single close","handlingStrategy":"try-catch","validationCode":"// ensure single ownership: never share a LockFile instance across scopes\n// assert !lockAlreadyClosed;","typeGuard":null,"tryCatchPattern":"try { jibOp(); } catch (IllegalStateException e) { if (e.getCause() instanceof IOException) { log(\"Lock cleanup failed\", e); } else throw e; }","preventionTips":["Use try-with-resources so LockFile is closed exactly once","Never delete lock files under the Jib cache while builds run","Monitor disk health and available file descriptors in CI"],"tags":["locking","file-io","illegal-state","resource-cleanup"],"backgroundTag":"file-write-failed","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}