apache/druid · error · IllegalArgumentException
Cannot add files of the same name, already have
Error message
Cannot add files of the same name, already have [%s]
What it means
Each file inside a SegmentFileV10 container must have a unique name because the container metadata indexes internal files by name. addWithChannel checks internalFiles.containsKey(name) and throws this IllegalArgumentException when a duplicate name is added. It prevents silently overwriting or shadowing an existing internal file.
Solutions
- Make internal file names unique by adding a distinguishing suffix (column name, version, index kind) before calling addWithChannel
- Ensure a single SegmentFileBuilderV10 instance is not reused to write the same file twice; create a new builder or a new container for a second write
- Check existing names with the builder's metadata before adding and skip/overwrite intentionally
Example fix
// before
builder.addWithChannel("__time.idx", size);
builder.addWithChannel("__time.idx", size2); // duplicate
// after
builder.addWithChannel("__time.idx.v1", size);
builder.addWithChannel("__time.idx.v2", size2); Defensive patterns
Strategy: validation
Validate before calling
// Java: track names you have already added
Set<String> used = new HashSet<>();
if (!used.add(name)) { throw new IllegalStateException("duplicate file name: " + name); } Try / catch
try {
builder.addWithChannel(name, size);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Cannot add files of the same name")) {
builder.addWithChannel(appendVersionSuffix(name), size);
} else { throw e; }
} Prevention
- Include a unique suffix (column name + index kind + version) in every internal file name
- Never reuse a single builder for multiple independent write sessions
- Maintain your own Set of names written and assert uniqueness before add
When it happens
Trigger: Calling addWithChannel(name, size) (directly or via add/makeColumn) twice with the same name within one container build, e.g. writing two versions of a column under the same file name in one builder session.
Common situations: Custom ingestion/segment-generation code writing multiple index files with the same generated name; a builder reused across bundles without clearing names; a bug in name generation omitting a version/suffix.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Cannot have a comma in the name of a file, got
- A local input source accepts only one of
- A local input source can set parameter
- A local input source requires one parameter of
- A local input source requires one property of
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/4581cd40c3fd5084.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/file/SegmentFileBuilderV10.java:203
}
}
@Override
public void add(String name, ByteBuffer bufferToAdd) throws IOException
{
try (SegmentFileChannel out = addWithChannel(name, bufferToAdd.remaining())) {
out.write(bufferToAdd);
}
}
@Override
public SegmentFileChannel addWithChannel(final String name, final long size) throws IOException
{
if (name.contains(",")) {
throw new IAE("Cannot have a comma in the name of a file, got[%s].", name);
}
if (internalFiles.containsKey(name)) {
throw new IAE("Cannot add files of the same name, already have [%s]", name);
}
ensureNameMatchesActiveBundle(name);
if (size > maxContainerSize) {
throw DruidException.forPersona(DruidException.Persona.ADMIN)
.ofCategory(DruidException.Category.RUNTIME_FAILURE)
.build(
"Serialized buffer size[%,d] for column[%s] exceeds the maximum[%,d]. "
+ "Consider adjusting the tuningConfig - for example, reduce maxRowsPerSegment, "
+ "or partition your data further.",
size, name, maxContainerSize
);
}
// If an outer writer is mid-write we can't append to the current container concurrently, route through a temp
// file that will be merged back into a container once the outer writer releases.
if (writerCurrentlyInUse) {
return delegateChannel(name, size);
}View on GitHub (pinned to 9b90983fd2)