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
- Create the object first with put(key, streamProvider, 0) (zero-length put is supported) and append subsequent chunks
- Skip the append entirely when there is nothing to write: only call append when contentLength > 0 or the object already exists
- 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
- Create objects with put() and use append() only for subsequent chunks of existing objects
- Skip write calls entirely when the buffer is empty — never append zero bytes to open a file
- Buffer output and flush only when data exists (len > 0) or the object already exists
- Write tests covering the first-flush-empty case for any custom OutputStream built on ObjectStorage
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
- File not found %s
- Unexpect end of stream, expected to write length:%s, actual
- Unexpect end of stream, expected length:%s, actual:%s
- Not supported
- Failed to create root dir. %s
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/ec4c4b4d72a274d5.
Report an issue: GitHub.