OrchardCMS/OrchardCore · error · AntivirusScanningException

The ClamAV antivirus scanner could not be reached while…

Error message

The ClamAV antivirus scanner could not be reached while scanning '{context.FileName}'.

What it means

The ClamAV file event handler catches SocketException from the clamd TCP connection and rethrows it as an AntivirusScanningException with this message. It means the upload pipeline could not establish or maintain a socket connection to the ClamAV daemon while scanning a file.

Solutions

  1. Verify ClamAV daemon is running and listening (e.g. `docker ps`, `systemctl status clamav-daemon`).
  2. Confirm options.Host and options.Port point at the correct clamd address (default 3310).
  3. Test connectivity from the app host: `telnet clamd-host 3310` or `nc -vz`.
  4. Check container networking/DNS (service name on the same Docker network) and firewall rules.

Example fix

// before
options.Host = "localhost"; // in a container, clamd is not on localhost
// after
options.Host = "clamd"; // docker-compose service name, port 3310
Defensive patterns

Strategy: retry

Validate before calling

// preflight connectivity check
using var tcp = new System.Net.Sockets.TcpClient();
await tcp.ConnectAsync(options.Host, options.Port); // throws if clamd unreachable

Try / catch

try
{
    await UploadFileAsync(stream);
}
catch (AntivirusScanningException ex) when (ex.InnerException is SocketException)
{
    logger.LogError(ex, "clamd unreachable at {Host}:{Port}", options.Host, options.Port);
    // surface a friendly 'service temporarily unavailable' message
}

Prevention

When it happens

Trigger: CreatingAsync calls _connectionFactory.Create(_options).ScanAsync and the TCP connect or stream I/O to options.Host:options.Port raises SocketException (host unresolvable/unreachable, connection refused, reset).

Common situations: clamd container not running or crashed, wrong host/port configuration, DNS resolution failure in containerized environments, network partition or firewall blocking port 3310.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/0e850b296db3119d. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.Antivirus/ClamAV/ClamAvFileEventHandler.cs:77

            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();
            }

            _logger.LogError(exception, "ClamAV failed while scanning '{FileName}'.", context.FileName);

            throw new AntivirusScanningException($"The ClamAV antivirus scanner failed while scanning '{context.FileName}'.", exception);
        }
        catch
        {
            if (scanStream != stream)
            {
                await scanStream.DisposeAsync();
            }

View on GitHub (pinned to 4306c0717f)