nathanmarz/storm · error · RuntimeException
Version already exists or data already exists
Error message
Version already exists or data already exists
What it means
VersionedStore.createVersion computes the path for a requested version and refuses it if that version already appears in getAllVersions() — i.e. a version directory/token already exists in the store. It throws RuntimeException to protect against overwriting an existing snapshot/transaction version.
Solutions
- Check existing versions first and pick a new version: if (store.getAllVersions().contains(v)) v = nextFreeVersion().
- On concurrent writers, derive the version from a shared monotonic source (zookeeper transaction id) so attempts don't collide.
- Clean up failed/incomplete versions (store.failVersion(path) or delete leftover dirs) before retrying the same version.
- If the existing version is a stale leftover of the same data, delete the directory and recreate.
Example fix
// before
String path = store.createVersion(txid); // throws if txid already committed
// after
if (store.getAllVersions().contains(txid)) {
LOG.info("Version " + txid + " already committed, skipping");
return;
}
String path = store.createVersion(txid); Defensive patterns
Strategy: validation
Validate before calling
if (store.getAllVersions().contains(txid)) {
throw new IllegalStateException("Version " + txid + " already exists; skipping or choose a new version");
} Try / catch
try {
String path = store.createVersion(txid);
} catch (RuntimeException e) {
if (e.getMessage().contains("already exists")) {
// treat as already-committed, recover idempotently
} else throw e;
} Prevention
- Make version creation idempotent: check getAllVersions() before creating
- Use a single writer or a shared monotonic source (zookeeper txid) for version numbers
- Clean up failed versions via failVersion before retrying the same version
When it happens
Trigger: Calling createVersion(long) (or the Long overload that delegates) with a version number previously created, or creating the same version concurrently from two processes/threads; retrying a create after a previous partially-successful attempt left the version directory on disk.
Common situations: Two workers or a failed-then-retried job both try to commit the same transaction id to a shared HDFS/state store; clock-derived or counter-derived versions reused after a crash; replaying a job without cleaning the store directory.
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
- is not a valid version
- Could not find component with id
- Don't know how to convert
- Each element of the list
- Field must be an Iterable of
AI-assisted analysis of nathanmarz/storm@cdb116e942 (2026-09-12).
Data as JSON: /api/errors/c262481397350854.
Report an issue: GitHub.
Appendix: source
Thrown at storm-core/src/jvm/backtype/storm/utils/VersionedStore.java:85
for(Long v: all) {
if(v <= maxVersion) return v;
}
return null;
}
public String createVersion() throws IOException {
Long mostRecent = mostRecentVersion();
long version = Time.currentTimeMillis();
if(mostRecent!=null && version <= mostRecent) {
version = mostRecent + 1;
}
return createVersion(version);
}
public String createVersion(long version) throws IOException {
String ret = versionPath(version);
if(getAllVersions().contains(version))
throw new RuntimeException("Version already exists or data already exists");
else
return ret;
}
public void failVersion(String path) throws IOException {
deleteVersion(validateAndGetVersion(path));
}
public void deleteVersion(long version) throws IOException {
File versionFile = new File(versionPath(version));
File tokenFile = new File(tokenPath(version));
if(versionFile.exists()) {
FileUtils.forceDelete(versionFile);
}
if(tokenFile.exists()) {
FileUtils.forceDelete(tokenFile);
} View on GitHub (pinned to cdb116e942)