eclipse-vertx/vert.x · error · FileSystemException

Cannot truncate file to size < 0

Error message

Cannot truncate file to size < 0

What it means

The truncate action in FileSystemImpl validates the requested length before touching the file and throws FileSystemException 'Cannot truncate file to size < 0' when a negative size is passed. Vert.x truncates via RandomAccessFile.setLength, which only accepts non-negative lengths, so the library fails fast with a clear message. This is a caller input-validation error, not an I/O failure.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:501

          Path source = resolveFile(from).toPath();
          Path target = resolveFile(to).toPath();
          Files.move(source, target, copyOptions);
        } catch (IOException e) {
          throw new FileSystemException(getFileMoveErrorMessage(from, to), e);
        }
        return null;
      }
    };
  }

  private BlockingAction<Void> truncateInternal(String p, long len) {
    Objects.requireNonNull(p);
    return new BlockingAction<Void>() {
      public Void perform() {
        try {
          String path = resolveFile(p).getAbsolutePath();
          if (len < 0) {
            throw new FileSystemException("Cannot truncate file to size < 0");
          }
          if (!Files.exists(Paths.get(path))) {
            throw new FileSystemException("Cannot truncate file " + path + ". Does not exist");
          }
          try (RandomAccessFile raf = new RandomAccessFile(path, "rw")) {
            raf.setLength(len);
          }
        } catch (IOException e) {
          throw new FileSystemException(getFileAccessErrorMessage("truncate", p) ,e);
        }
        return null;
      }
    };
  }

  private BlockingAction<Void> chmodInternal(String path, String perms) {
    return chmodInternal(path, perms, null);
  }

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Clamp or validate the target length: if (len < 0) len = 0; or reject the input before calling truncate.
  2. Recompute the intended size — verify the offset/bytes-to-remove against the actual file size (fs.props(path).size()).
  3. If the size comes from configuration, validate it is >= 0 at load time.
  4. If you intended to empty the file, pass 0 explicitly.

Example fix

// before
long len = props.size() - consumed; // may be negative
vertx.fileSystem().truncateBlocking(path, len);
// after
long len = Math.max(0, props.size() - consumed);
vertx.fileSystem().truncateBlocking(path, len);
Defensive patterns

Strategy: validation

Validate before calling

long len = computeTargetSize();
if (len < 0) throw new IllegalArgumentException("truncate size must be >= 0, got " + len);
vertx.fileSystem().truncateBlocking(path, len);

Type guard

static Long nonNegativeSize(Long size) {
  return (size == null || size < 0) ? 0L : size;
}

Try / catch

try {
  fs.truncateBlocking(path, len);
} catch (FileSystemException e) {
  if (e.getMessage().contains("size < 0")) {
    fs.truncateBlocking(path, 0); // or reject the request upstream
  } else throw e;
}

Prevention

When it happens

Trigger: vertx.fileSystem().truncate(path, len) or truncateBlocking with a negative len — typically a computed size such as fileLength - bytesRemoved where the subtraction went negative.

Common situations: Truncating to 'current size minus offset' when the offset exceeds the file size; parsing a size from config/CLI where a negative slips through; integer overflow producing a negative value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/db8bb42b5189c3bd. Report an issue: GitHub.