apache/hadoop · error · NotAppendableException

%s is not appendable because append non-existed object with

Error message

%s is not appendable because append non-existed object with zero byte is not supported.

What it means

FileStore.append() refuses to append to a key that has no backing file when the declared contentLength is zero: appending zero bytes to a nonexistent object would have to create an empty file, which this local object-store emulation chooses not to support. It throws the typed NotAppendableException so callers can distinguish this case from other failures.

Source

Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/object/FileStore.java:187

    }
  }

  @Override
  public byte[] put(String key, InputStreamProvider streamProvider, long contentLength) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Key should not be empty.");
    File destFile = path(encode(key)).toFile();
    copyInputStreamToFile(streamProvider.newStream(), destFile, contentLength);

    return ObjectInfo.isDir(key) ? Constants.MAGIC_CHECKSUM : getFileChecksum(destFile.toPath());
  }

  @Override
  public byte[] append(String key, InputStreamProvider streamProvider, long contentLength) {
    Preconditions.checkArgument(!Strings.isNullOrEmpty(key), "Key should not be empty.");
    File destFile = path(encode(key)).toFile();
    if (!destFile.exists()) {
      if (contentLength == 0) {
        throw new NotAppendableException(String.format(
            "%s is not appendable because append non-existed object with "
                + "zero byte is not supported.", key));
      }
      return put(key, streamProvider, contentLength);
    } else {
      appendInputStreamToFile(streamProvider.newStream(), destFile, contentLength);
      return ObjectInfo.isDir(key) ? Constants.MAGIC_CHECKSUM : getFileChecksum(destFile.toPath());
    }
  }

  private static File createTmpFile(File destFile) {
    String tmpFilename = ".tmp." + UUIDUtils.random();
    File file = new File(destFile.getParentFile(), tmpFilename);

    try {
      if (!file.exists() && !file.createNewFile()) {
        throw new RuntimeException("failed to create tmp file");
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Create the object first with put(key, streamProvider, 0) (zero-length put is supported) and append subsequent chunks
  2. Skip the append entirely when there is nothing to write: only call append when contentLength > 0 or the object already exists
  3. Catch the typed NotAppendableException and fall back to put() for the first chunk

Example fix

// before
storage.append(key, () -> new ByteArrayInputStream(new byte[0]), 0); // key absent -> NotAppendableException
// after
if (storage.objectStatus(key) == null) {
  storage.put(key, () -> new ByteArrayInputStream(new byte[0]), 0); // create explicitly
} else {
  storage.append(key, () -> new ByteArrayInputStream(new byte[0]), 0);
}
Defensive patterns

Strategy: validation

Validate before calling

boolean exists = storage.objectStatus(key) != null;
if (!exists && contentLength == 0) {
  storage.put(key, streamProvider, 0); // zero-length put creates the object
} else {
  storage.append(key, streamProvider, contentLength);
}

Try / catch

try {
  storage.append(key, streamProvider, contentLength);
} catch (org.apache.hadoop.fs.tosfs.object.exceptions.NotAppendableException e) {
  // first chunk of a new object: create it, then append the rest
  storage.put(key, streamProvider, contentLength);
}

Prevention

When it happens

Trigger: storage.append(key, streamProvider, 0) (or append(key, bytes, 0, 0)) when no object exists at key — e.g. a flush of an empty buffer opening a new file, or a caller that initializes files by appending an empty chunk before writing data.

Common situations: OutputStream implementations that call append() on first write even when nothing has been buffered yet; HDFS-style append semantics ported to the filestore where create() is expected to happen implicitly; directory-marker keys being appended with zero length.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/ec4c4b4d72a274d5. Report an issue: GitHub.