apache/hadoop · error · IOException
Rename unsuccessful : '%s' to '%s'
Error message
Rename unsuccessful : '%s' to '%s'
What it means
flush() commits by renaming files: the new store is written to <path>_NEW, the current file is renamed to <path>_OLD, and renameOrFail promotes _NEW onto the live path. fs.rename returned false and the provider converts that into an IOException naming both paths. This is a filesystem-level refusal - typically an existing destination, missing permissions, or non-atomic rename semantics - not an HDFS exception.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/JavaKeyStoreProvider.java:643
renameOrFail(path, oldPath);
return true;
} catch (FileNotFoundException e) {
return false;
}
}
private void revertFromOld(Path oldPath, boolean fileExisted)
throws IOException {
if (fileExisted) {
renameOrFail(oldPath, path);
}
}
private void renameOrFail(Path src, Path dest)
throws IOException {
if (!fs.rename(src, dest)) {
throw new IOException("Rename unsuccessful : "
+ String.format("'%s' to '%s'", src, dest));
}
}
@Override
public String toString() {
return uri.toString();
}
/**
* The factory to create JksProviders, which is used by the ServiceLoader.
*/
public static class Factory extends KeyProviderFactory {
@Override
public KeyProvider createProvider(URI providerName,
Configuration conf) throws IOException {
if (SCHEME_NAME.equals(providerName.getScheme())) {
return new JavaKeyStoreProvider(providerName, conf);View on GitHub (pinned to 2add963021)
Solutions
- Delete stale <keystore>_NEW and <keystore>_OLD files left by an interrupted flush, then retry
- Verify write permission on the keystore's parent directory for the running user
- Ensure exactly one writer per keystore file; serialize flush across processes
- Keep keystores on filesystems with proper rename support (HDFS or local POSIX FS)
Defensive patterns
Strategy: validation
Validate before calling
// before flush: clear stale side files from an interrupted run and check dir writability org.apache.hadoop.fs.Path p = new org.apache.hadoop.fs.Path(providerUri); FileSystem fs = p.getFileSystem(conf); fs.delete(new Path(p + "_NEW"), false); fs.delete(new Path(p + "_OLD"), false);
Try / catch
try { provider.flush(); } catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith("Rename unsuccessful")) { // remove stale _NEW/_OLD, verify parent dir permissions, retry flush once } else { throw e; } } Prevention
- One writer per keystore file; serialize flush across processes
- After crashes, clean *_NEW/_OLD before next use
- Monitor write permissions on the keystore directory
- Keep keystores on filesystems with atomic rename support
When it happens
Trigger: A leftover *_NEW or destination file from a crashed flush blocks the rename; no write permission on the keystore's parent directory; two processes flushing the same keystore concurrently; a filesystem (NFS, object-store mount) without POSIX rename guarantees.
Common situations: Two daemons sharing one keystore file; keystore directory made read-only; keystore stored on a mount with unusual rename semantics; interrupted process leaving side files behind.
Related errors
- Can't set metadata key ${entry.getKey()}
- Can't store keystore ${this}
- Cannot overwrite an existing file: %s
- Cannot rename because path does not exist: %s
- Wrong key length. Required ${options.getBitLength()}, but go
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/12bd37474755f1a8.
Report an issue: GitHub.