GoogleContainerTools/jib · error · IllegalStateException

Unable to release lock

Error message

Unable to release lock

What it means

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.

Source

Thrown at jib-core/src/main/java/com/google/cloud/tools/jib/filesystem/LockFile.java:86

      fileLock = outputStream.getChannel().lock();
      return new LockFile(lockFile, fileLock, outputStream);

    } finally {
      if (fileLock == null) {
        outputStream.close();
      }
    }
  }

  /** Releases the lock file. */
  @Override
  public void close() {
    try {
      fileLock.release();
      outputStream.close();

    } catch (IOException ex) {
      throw new IllegalStateException("Unable to release lock", ex);

    } finally {
      Preconditions.checkNotNull(lockMap.get(lockFilePath)).unlock();
    }
  }
}

View on GitHub (pinned to fb949e2676)

Solutions

  1. Ensure each LockFile is closed exactly once (one try-with-resources scope)
  2. Do not delete or tamper with lock files under the Jib cache directory while a build runs
  3. Check disk health and filesystem mounts
  4. Catch IllegalStateException around the Jib operation and inspect the cause

Example fix

// before
LockFile lock = new LockFile(path);
lock.close();
lock.close(); // double close -> IllegalStateException
// after
try (LockFile lock = new LockFile(path)) {
  // critical section
} // single close
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure single ownership: never share a LockFile instance across scopes
// assert !lockAlreadyClosed;

Try / catch

try { jibOp(); } catch (IllegalStateException e) { if (e.getCause() instanceof IOException) { log("Lock cleanup failed", e); } else throw e; }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/jib@fb949e2676 (2026-09-06). Data as JSON: /api/errors/0375bf90756de16c. Report an issue: GitHub.