OrchardCMS/OrchardCore · error · AntivirusScanningException
The ClamAV antivirus scanner timed out while scanning
Error message
The ClamAV antivirus scanner timed out while scanning '{context.FileName}'. What it means
OrchardCore's ClamAV antivirus module scans every uploaded file through a ClamAV INSTREAM connection. When the scan is cancelled or exceeds the configured timeouts, the OperationCanceledException is caught in CreatingAsync and rethrown as an AntivirusScanningException carrying this message, after logging the original exception.
Solutions
- Increase ClamAV ConnectTimeoutSeconds/TransferTimeoutSeconds in the antivirus options to cover your largest uploads.
- Verify the clamd daemon is healthy and not overloaded (check clamd logs, MaxScanSize, CPU).
- Reduce upload size limits or move ClamAV closer to the app to cut scan latency.
- Implement client retry with backoff for uploads that fail due to transient timeout.
Example fix
// before
services.AddClamAv(options => { options.Host = "clamd"; options.Port = 3310; });
// after
services.AddClamAv(options => { options.Host = "clamd"; options.Port = 3310; options.ConnectTimeoutSeconds = 30; options.TransferTimeoutSeconds = 300; }); Defensive patterns
Strategy: try-catch
Validate before calling
// before upload, ensure timeouts cover the file size
if (file.Length > estimatedMaxBytesPerSecond * options.TransferTimeoutSeconds)
{
// warn: scan likely to time out
} Try / catch
try
{
await UploadFileAsync(stream);
}
catch (AntivirusScanningException ex) when (ex.InnerException is OperationCanceledException)
{
logger.LogWarning(ex, "Antivirus scan timed out; retry or raise timeouts.");
} Prevention
- Size ConnectTimeoutSeconds/TransferTimeoutSeconds to your largest allowed upload.
- Keep clamd on a low-latency network path from the app.
- Monitor clamd load and scan durations; alert on approaching timeouts.
- Cap upload size limits consistently with scan timeouts.
When it happens
Trigger: Uploading a file triggers CreatingAsync; the ClamAV ScanAsync call exceeds ConnectTimeoutSeconds/TransferTimeoutSeconds, or the CancellationToken fires (request abort, server shutdown) mid-scan.
Common situations: Large uploads over slow links to a remote clamd, undersized timeout settings, an overloaded or under-provisioned ClamAV daemon, or clients cancelling uploads.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- The ClamAV antivirus scanner failed while scanning
- The ClamAV antivirus scanner is enabled but the connection…
- The ClamAV antivirus scanner is enabled but the transfer…
- Failed to acquire a lock before activating the tenant
- The file ' ' was rejected.
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/510b65acc89ae4cd.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore.Modules/OrchardCore.Antivirus/ClamAV/ClamAvFileEventHandler.cs:66
if (TryCreateFailureResult(context, scanStream, response) is { } failureResult)
{
return failureResult;
}
scanStream.Position = 0;
return FileCreatingResult.Success(scanStream);
}
catch (OperationCanceledException exception)
{
if (scanStream != stream)
{
await scanStream.DisposeAsync();
}
_logger.LogError(exception, "ClamAV timed out while scanning '{FileName}'.", context.FileName);
throw new AntivirusScanningException($"The ClamAV antivirus scanner timed out while scanning '{context.FileName}'.", exception);
}
catch (SocketException exception)
{
if (scanStream != stream)
{
await scanStream.DisposeAsync();
}
_logger.LogError(exception, "ClamAV could not be reached while scanning '{FileName}'.", context.FileName);
throw new AntivirusScanningException($"The ClamAV antivirus scanner could not be reached while scanning '{context.FileName}'.", exception);
}
catch (IOException exception)
{
if (scanStream != stream)
{
await scanStream.DisposeAsync();
}View on GitHub (pinned to 4306c0717f)