apache/hadoop · error · NotAppendableException
%s is not appendable.
Error message
%s is not appendable.
What it means
In FNS (general-purpose bucket) mode, fnsAppend first heads the object; if it exists but was not created as an appendable object (it was written by a normal PUT or multipart upload), the connector throws NotAppendableException("<key> is not appendable."). Only objects originally created via appendObject can be appended, matching TOS semantics.
Source
Thrown at hadoop-cloud-storage-project/hadoop-tos/src/main/java/org/apache/hadoop/fs/tosfs/object/tos/TOS.java:508
}
offset = obj.size();
preCrc64 = obj.crc64ecma();
}
AppendObjectOutput res =
client.appendObject(bucket, key, streamProvider, offset, contentLength, preCrc64,
defaultAcl);
return ObjectInfo.isDir(key) ? Constants.MAGIC_CHECKSUM :
parseChecksum(res.getRequestInfo().getHeader(), checksumInfo);
}
private byte[] fnsAppend(String key, InputStreamProvider streamProvider, long contentLength) {
checkAvailableClient();
TosObjectInfo obj = innerHead(key);
if (obj != null) {
if (!obj.appendable()) {
throw new NotAppendableException(String.format("%s is not appendable.", key));
}
if (contentLength == 0) {
return obj.checksum();
}
} else if (contentLength == 0) {
throw new NotAppendableException(String.format("%s is not appendable because append"
+ " non-existed object with zero byte is not supported.", key));
}
long offset = obj == null ? 0 : obj.size();
String preCrc64 = obj == null ? null : obj.crc64ecma();
AppendObjectOutput res;
try {
res = client.appendObject(bucket, key, streamProvider, offset, contentLength, preCrc64,
defaultAcl);
} catch (TosServerException e) {
if (e.getStatusCode() == 409 && APPEND_NOT_APPENDABLE.equals(e.getEc())) {
throw new NotAppendableException(String.format("%s is not appendable.", key));View on GitHub (pinned to 2add963021)
Solutions
- Rewrite the object from scratch through the append path if append semantics are required
- Before calling append, treat any existing object written by a normal PUT as non-appendable and fail with a clear message
- Avoid FileSystem.append on tos:// for files not created appendable; use copy-on-write or part-file schemes instead
Example fix
// before
storage.append(key, data);
// after: fail fast with actionable context
try {
storage.append(key, data);
} catch (NotAppendableException e) {
throw new IOException(key
+ " was created by a normal upload and cannot be appended;"
+ " rewrite it via the append/create path instead", e);
} Defensive patterns
Strategy: try-catch
Try / catch
try {
storage.append(key, data);
} catch (NotAppendableException e) {
throw new IOException(key
+ " was created by a normal upload and cannot be appended;"
+ " rewrite it via the append path instead", e);
} Prevention
- Do not call append() on objects written by the normal put/multipart path
- Use one write mode per key for the object's lifetime
- Prefer part-file or copy-on-write patterns over appending existing objects
When it happens
Trigger: append(key, ...) where key was previously written by the regular write path (put/multipart upload), then something calls append on it — e.g. FileSystem.append() on an existing tos:// file created by a normal write job.
Common situations: Calling append() on files created by the standard output stream; mixing write modes on the same key across jobs; assuming S3/HDFS-like append semantics where any file can be appended.
Related errors
- %s is not appendable because append non-existed object with
- Not supported
- tos: request interrupted.
- Expected checksum is %s while actual checksum is %s
- Object %s doesn't exit
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/b6666fbd86bbd922.
Report an issue: GitHub.