jenkinsci/jenkins · error · IOException
remote file operation failed
Error message
remote file operation failed
What it means
Thrown by FilePath.actAsync when wrapping the FileCallable and dispatching it over the channel fails with IOException. The fresh IOException preserves the caller's stack trace (remote exceptions lose the calling frame), with the original as cause. This wraps channel-level failures, not the inner callable's business exceptions.
Source
Thrown at core/src/main/java/hudson/FilePath.java:1300
protected void after() {}
}
/**
* Executes some program on the machine that this {@link FilePath} exists,
* so that one can perform local file operations.
*/
public <T> Future<T> actAsync(final FileCallable<T> callable) throws IOException, InterruptedException {
try {
DelegatingCallable<T, IOException> wrapper = new FileCallableWrapper<>(callable, this);
for (FileCallableWrapperFactory factory : ExtensionList.lookup(FileCallableWrapperFactory.class)) {
wrapper = factory.wrap(wrapper);
}
return (channel != null ? channel : localChannel)
.callAsync(wrapper);
} catch (IOException e) {
// wrap it into a new IOException so that we get the caller's stack trace as well.
throw new IOException("remote file operation failed", e);
}
}
/**
* Executes some program on the machine that this {@link FilePath} exists,
* so that one can perform local file operations.
*/
public <V, E extends Throwable> V act(Callable<V, E> callable) throws IOException, InterruptedException, E {
if (channel != null) {
// run this on a remote system
return channel.call(callable);
} else {
// the file is on the local machine
return callable.call();
}
}
/**View on GitHub (pinned to 2e228ff40b)
Solutions
- Ensure the agent is online and the channel is healthy before the call.
- Make the FileCallable and all its fields Serializable (use MasterToSlaveFileCallable).
- Inspect the cause for NotSerializableException and annotate/strip offending fields.
- Check FileCallableWrapperFactory extensions for failures.
Example fix
// before
fp.actAsync(in -> doWork(in)); // lambda may not be serializable
// after
fp.actAsync(new MasterToSlaveFileCallable<Result>() {
private static final long serialVersionUID = 1L;
public Result invoke(File f, VirtualChannel ch) { return doWork(f); }
}); Defensive patterns
Strategy: validation
Validate before calling
if (callable instanceof Serializable && channel != null && channel.isClosingOrClosed()) {
// channel unhealthy — defer or fail fast before actAsync
} Type guard
static boolean isRemotable(Object c) { return c instanceof Serializable; } Try / catch
try {
Future<T> f = fp.actAsync(callable);
} catch (IOException e) {
// 'remote file operation failed' — check cause for channel/serialization issues
if (e.getCause() instanceof NotSerializableException) { /* make callable serializable */ }
} Prevention
- Always use MasterToSlaveFileCallable (serializable) for act/actAsync.
- Check agent/channel health before dispatching remote file ops.
- Audit FileCallableWrapperFactory extensions for failures.
When it happens
Trigger: Remoting channel is closed/disconnected; callable or its arguments are not serializable; FileCallableWrapperFactory wrapping throws; channel.callAsync raises IOException before dispatch.
Common situations: Agent went offline mid-operation; passing a non-Serializable lambda/closure to actAsync; channel degraded after a restart; custom FileCallableWrapperFactory throws.
Related errors
- Failed to unpack %s (%d bytes read)
- Failed to join the process
- Failed to create a temp file on ${remote}
- Failed to create a temp directory on ${remote}
- Can not call launch on a dummy launcher.
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/034cb70229699a2e.
Report an issue: GitHub.