xpipe-io/xpipe · error · IOException
Source file ${sourceFile} input size mismatch: Expected ${ex
Error message
Source file ${sourceFile} input size mismatch: Expected ${expected} but got ${actual}. Did the source file get updated? What it means
Thrown during transferFile when the number of bytes actually read from the source file is less than the expected file size recorded when the transfer was planned. The operation treats a short read as corruption risk and kills the streams, wrapping it in an IOException.
Source
Thrown at app/src/main/java/io/xpipe/app/browser/file/BrowserFileTransferOperation.java:622
killStreams.set(true);
break;
}
outputStream.write(buffer, 0, read);
transferred.addAndGet(read);
readCount.addAndGet(read);
if (reportProgress) {
updateProgress(
new BrowserTransferProgress(sourceFile.getFileName(), transferred.get(), total.get()));
}
}
outputStream.flush();
inputStream.transferTo(OutputStream.nullOutputStream());
var incomplete = !killStreams.get() && readCount.get() < expectedFileSize;
if (incomplete) {
throw new IOException("Source file " + sourceFile + " input size mismatch: Expected "
+ expectedFileSize + " but got " + readCount.get() + ". Did the source file get updated?");
}
} catch (Exception ex) {
exception.set(ex);
killStreams.set(true);
}
});
thread.start();
while (true) {
var alive = thread.isAlive();
var cancelled = cancelled();
if (cancelled) {
killStreams(thread, readCount, false);
break;
}
View on GitHub (pinned to d85ca821ba)
Solutions
- Retry the transfer after the source file stops changing
- Exclude actively written files (logs, temp files) from the transfer
- Snapshot/quiesce the source (stop the writer) before transferring
- Verify connection stability to the remote system and retry
Example fix
// before
transferFiles(List.of("/var/log/app.log")) // file being actively written
// after
// copy or rotate the log first, then transfer the static file
transferFiles(List.of("/var/log/app.log.1")) Defensive patterns
Strategy: retry
Validate before calling
async function transferStable(transfer, files, retries = 2) {
for (let i = 0; i <= retries; i++) {
try { return await transfer(files); }
catch (e) {
if (!String(e.message).includes('size mismatch') || i === retries) throw e;
}
}
} Try / catch
try {
await transferFiles(files);
} catch (e) {
if (String(e.message).includes('size mismatch')) {
// source changed mid-transfer; quiesce writer and retry
}
} Prevention
- Exclude actively written files (logs, temp files) from transfers
- Stop writers / rotate logs before transferring
- Retry on unstable remote connections
When it happens
Trigger: The source file shrunk or was truncated/rewritten between size capture and streaming, or the underlying stream ended early (network drop, remote process writing the file concurrently).
Common situations: Transferring log files actively being rotated or truncated, files modified by a running job on the remote host, unstable SSH/network connections terminating the stream early.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Target ${path} is not a directory
- Mixed source file systems
- Directory creation in ${dataDirectory} failed silently
- File path " + msg.getPath() + " is not absolute
- File " + msg.getPath() + " does not exist
AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/df6d41c349bc067b.
Report an issue: GitHub.