CompleteFTP: System.OutOfMemoryException during SFTP, or a service that stops responding
Sessions are dying with System.OutOfMemoryException in the diagnostics log, or the whole server has
gone quiet: transfers crawl, new logins time out, CompleteFTP Manager will not connect, and a service
restart brings everything back for a day or a week. Those two things arrive in the same sentence from
users but they are separate failures, they leave different evidence, and the second one frequently has
no out-of-memory error in it at all.
Three names are used throughout, because the words "client" and "server" point in opposite directions depending on which one you mean:
- your CompleteFTP server is the CompleteFTP service on the machine you administer.
- the connecting client is whatever connects to it over SFTP: WinSCP, FileZilla, OpenSSH
sftp, a partner's scheduler, your own application. - the upstream server is the FTP/SFTP server behind your CompleteFTP server when it is running as a multiprotocol gateway.
If System.OutOfMemoryException is being thrown inside your own application while it talks to a
remote server, the memory being exhausted is your application's, not CompleteFTP's, and nothing below
applies to it.
Which situation are you in?
Answer from what people are telling you right now.
Which parts are shared. The short version and Where the limits are below apply to both cases, and so do most of the entries in When it doesn't work, which are tagged with the cases they belong to. The two case sections are the branch: read the one you land on and skip the other.
| Case | What is happening to new SFTP logins | What CompleteFTP Manager does | Read |
|---|---|---|---|
| A | New logins still succeed. Individual sessions fail, some transfers break part way, some users are unaffected | Connects normally | Case A |
| B | New logins hang and time out, or are refused. Existing sessions stall | Cannot connect, or connects and then times out | Case B |
Telling them apart from the log alone
Both cases can put System.OutOfMemoryException in Diagnostics.log, so the exception text does not
separate them. The session number does.
Every log line carries a tag of the form
[Session.{n}:{site name}.{port}:{user name}:{remote IP}]. That {n} is a counter that starts at 1
when the service starts and increases by one for every accepted connection, logged in or not.
Confirm the service has not restarted under you before you read anything into the counter. The
counter resets to 1 on every start, so a restart makes a stalled server look like a busy one. The
Linux unit is configured to restart itself automatically after a crash, which makes this the normal
case there rather than the exception: check uptime with systemctl status completeftp (the Active:
line) and cross-check against the INFO Server ... Starting server lines in Diagnostics.log, which
are written once per start on both platforms. On Windows nothing restarts the service unless recovery
actions were configured, so one Starting server line usually means one run.
With uptime established:
- Session numbers keep climbing after the incident started. Your CompleteFTP server is still accepting connections. That is Case A.
- Session numbers stop advancing, and what remains in the log is repeats from the same handful of sessions, or nothing at all. Nothing new is getting in. That is Case B.
One line decides it on its own. This one is thrown while accepting a brand-new connection, and it means memory ran out before the connection existed:
2026-08-03 09:14:22,118 ERROR SocketListener [Session.481233:Default Site.22:user?:10.4.11.60] OnConnected failed: Exception of type 'System.OutOfMemoryException' was thrown.
If that line is present, treat it as Case B regardless of what else is in the log.
The session counter is also a rate meter. Divide the highest session number by the time since the service last started. Half a million sessions in three days is roughly two connections per second, sustained, which is a load question rather than a memory question.
The short version
- Record the memory figure before you restart anything. A restart erases the only measurement
that distinguishes "the process grew" from "the machine was full".
- Windows: Task Manager → Details →
CompleteFTPService.exe, the Working set (memory) column. - Linux: the server runs as
dotnet /usr/lib/completeftp/bin/completeftp.dll. Get its process ID withsystemctl show completeftp -p MainPIDand read its resident set withps -o rss= -p <pid>(kilobytes). Resident set is the figure that corresponds to the Windows working set. TheMemory:line insystemctl statusis the whole control group and reads higher, so do not mix the two.
- Windows: Task Manager → Details →
- Note the highest
Session.number inDiagnostics.logand the time the service last started. That gives you the case above and your connection rate. - Turn the logging level up to Debug and leave it there until it happens again. Your
CompleteFTP server reports its own memory usage only at Debug, and raising the level is not
retroactive: a log captured at the default
Informationlevel will contain no memory lines, which is not evidence that memory was fine. The procedure is in How to enable debug logging in CompleteFTP. - Then:
- Case A → work through the per-session allocations. Admissions are healthy; one kind of request is not.
- Case B → restore service first, then bound what exhausted it. Restarting is the right immediate move here, once step 1 is done.
Where the limits are, and what units they use
Nothing in this table is set to a protective value out of the box. Max. non-HTTP connections to site
ships as 0, which means unlimited, and Max. connections per user is unset, which also means
unlimited. Both cases below refer back to this table.
CompleteFTP Manager is a Windows application. Administering a Linux server means either running the
manager on a Windows machine and pointing it at the server's admin port, or using the completeftp
command line on the server itself, which is enabled by default on Linux.
The manager shows timeouts in seconds and disk quotas in MB. The CLI and JSS properties are
the stored values, which are milliseconds and bytes. Setting timeoutIdle=300 from the
command line asks for 300 milliseconds, not five minutes.
| What it does | CompleteFTP Manager | CLI property | CLI unit | Shipped default |
|---|---|---|---|---|
| Caps total SFTP/FTP/FTPS connections to a site | Site → Limits and Timeouts → Max. non-HTTP connections to site | maxConnections |
count | 0 (unlimited) |
| Caps connections held by one account | Site → Limits and Timeouts → Max. connections per user | maxConnectionsPerUser |
count | unset (unlimited) |
| Closes a connection that has not logged in | Site → Limits and Timeouts → Timeout for logging in (seconds) | timeoutLogin |
ms | 60,000 (60 s) |
| Closes a logged-in session that sends nothing | Site → Limits and Timeouts → Timeout for idle sessions (seconds) | timeoutIdle |
ms | 300,000 (5 min) |
| Socket read/write timeout during transfers | Site → Limits and Timeouts → Timeout for stalled transfers (seconds) | timeoutStalled |
ms | 60,000 (60 s) |
| Login attempts allowed per session | Site → Limits and Timeouts → Max. allow login attempts | maxLoginAttempts |
count | 3 |
| Failed logins before an IP is banned | Site → IP Filtering and Auto-Banning → Auto-Banning → Number of failures allowed in period | autoBanTriggerCount |
count | 10 |
| Window those failures must fall in | Site → IP Filtering and Auto-Banning → Auto-Banning → Failure counting period (seconds) | autoBanTriggerPeriod |
ms | 300,000 (5 min) |
| How long the ban lasts | Site → IP Filtering and Auto-Banning → Auto-Banning → Duration of ban (seconds) | autoBanDuration |
ms | 3,600,000 (1 hour) |
| Per-user disk quota (drives size watchers) | User → Quotas and Limits → Disk usage (MB) | quotaStorage |
bytes | unset |
| Per-user transfer rate cap | User → Quotas and Limits → Download (kB/s), Upload (kB/s) | quotaSpeedDownload, quotaSpeedUpload |
bytes/s | unset |
Setting 0 in the manager's timeout fields displays as No timeout and means infinite, not
immediate. Entering a negative number in Disk usage (MB) clears the quota rather than setting one.
Changes reach the running server when you click APPLY CHANGES in the manager. From the command line the equivalent is one invocation per property, which applies itself:
completeftp site set "Default Site" maxConnections=400
completeftp site set "Default Site" maxConnectionsPerUser=20
completeftp site set "Default Site" timeoutLogin=30000
Neither route requires a service restart.
Case A. Sessions fail with an out-of-memory exception while logins keep succeeding
Your CompleteFTP server is up, admissions are working, and a subset of sessions is being killed. The allocation that failed belongs to one session's work, so the question is which work.
1. Get the exception, not just the first line. The message and the exception are logged as
separate lines. Errors.log and the manager's real-time view show you the message; the exception
type and its stack are in Diagnostics.log immediately after it. Take that file, not a screenshot of
the error list.
2. Establish whether the process is actually large. With Debug logging on, your CompleteFTP server logs its own working set on every login and every logout:
2026-08-03 09:15:02,441 DEBUG MemoryUsage [Session.481240:Default Site.22:jdoe:10.4.11.60] Working set = 128.44 MB
Read a day of those. A process that sits in the low hundreds of MB and then throws
System.OutOfMemoryException did not fill itself; something else on the machine took the memory, or
a single allocation was very large. A process whose working set climbs steadily across the day and
never falls back after logouts is the opposite problem, and belongs in Case B.
3. Find which operation throws. Match the timestamp to the SFTP request in the same session. The three that recur:
- A file read that fails:
ERROR FileDetails [...] /path/to/file: read file failed, with the exception on the next line. Note the file size. - A packet-processing failure:
ERROR SFTPConnection [...] Exception thrown in packet processing:followed by the exception. See Reading the output for what the connecting client is told when this happens. - A receive failure:
ERROR SFTPConnection [...] Receive error: Exception of type 'System.OutOfMemoryException' was thrown.
4. Check what else the machine is doing at that moment. Anti-virus scanning the transfer directory, a backup agent, another service on the same box. Storage and file-system work performed inside your CompleteFTP server's process counts against its address space even when the file itself is on a network share.
5. If it is one user or one folder, cap that user rather than the site. Max. connections per user
bounds the number of concurrent sessions a single account can hold, which bounds the number of
concurrent transfers it can run. It is the smallest change that stops one client starving the rest,
and it does not affect anyone else.
Case B. The service is running but nothing is getting through
New logins hang or are refused, the manager cannot connect, and stopping and starting the service fixes it for a while. Recovery and diagnosis are separate jobs, in that order.
1. Recover. Take the memory figure and the highest session number first, then restart:
Services → Complete FTP Server → Restart, or sc stop CompleteFTP then sc start CompleteFTP, on
Windows; systemctl restart completeftp on Linux.
While you are in the Windows Services console, check Recovery on Complete FTP Server and set Restart the Service if it says Take No Action. An upgrade does not add recovery actions to a service that already exists, so a server upgraded from an old installation often has none. The Linux unit already restarts itself after a crash.
If the service will not stop, do not assume it is stuck inside CompleteFTP. Raising the logging level to Debug before issuing the stop makes the log show how far shutdown got, but if CompleteFTP Manager cannot connect there is no way to raise it at that moment. This is the argument for leaving Debug on between incidents rather than trying to switch it on during one.
2. Decide whether it filled up or seized up. These need different fixes:
- Filled up. The
Working setlines climb across the run and do not come back down, or the machine's own memory is exhausted at the moment of failure. The accept-timeOnConnected failedline above is the strongest single indicator. - Seized up. Memory is unremarkable. What is exhausted is connections, threads or CPU. Look for
a very high session number relative to uptime, hundreds of established connections, or the
CompleteFTP process pinned near 100% CPU. Read the CPU figure from the same process you measured in
step 1: the CPU column in Task Manager on Windows,
top -p <pid>on Linux.
3. Count sessions, at the next occurrence. This measurement only exists while the server is still in the bad state, so it is what you do before restarting if anything can still reach the server, and otherwise what you prepare for next time.
Monitoring → Connections in CompleteFTP Manager lists Site, Username, Protocol, Remote Address, Local Port, Connected and Logged In per live connection, with Kill selected connection(s) and Kill all connections. Sessions that show a Connected time but no Logged In time, in quantity, are connections that never authenticated.
The manager is often the thing that cannot connect in this case, so on Linux use
completeftp monitor connection list --site "Default Site" and
completeftp monitor connection kill <sessionID> instead. On Windows the same commands exist but the
admin CLI is off by default: enabling it changes the service binary path and needs a service
restart, so it is preparation to do now, not a step you can take mid-incident. The guide page
the Windows admin CLI has the procedure.
4. Set the two limits that bound the damage. Both are on the site, both take effect without a restart:
Max. non-HTTP connections to site. Once the site is over this number, a further SFTP connection is refused at the point it asks to authenticate. Your CompleteFTP server logsWARN SFTPConnection [...] Maximum site connections exceeded - 400 allowedand the connecting client is disconnected with the textToo many connections to this site. Pick a number your machine has been observed to carry, not an aspirational one: refusing the 401st connection is a far better outcome than becoming unreachable to all 400.Max. connections per user, so that one runaway scheduler cannot consume the site limit by itself.
5. If it seized up, look at what blocks per session, in this order: disk-usage quotas, per-user speed limits, and any file-system extension or gateway hop. All three are covered as failure modes below.
When it doesn't work
Ordered by how often each turns up in support tickets. The case tags say which situation the item belongs to.
1. The machine really was out of memory, and CompleteFTP was the biggest process rather than the guilty one. (A, B) The CompleteFTP service is a 64-bit process, so it has no 2 GB address ceiling of its own: when it cannot allocate, the machine could not allocate. Check the page file, the other services on the box, and whether the VM has been resized. A working set of a few hundred MB under load is normal; a working set that is a large fraction of physical RAM is the finding.
2. Connections accumulate because nothing is bounding them. (B) With both connection limits at their shipped unlimited values, the number of simultaneous sessions is bounded only by the machine. A client that reconnects several times a second, or a partner whose retry loop has no backoff, will reach that boundary. The session counter and the Connections tab both quantify it, and the fix is step 4 of Case B.
3. Connections that never log in. (A, B) Auto-banning counts failed authentication attempts
only. An address that opens connections and never offers a credential is never banned, no matter how
many it opens, so an unauthenticated flood does not appear in the auto-ban list. What bounds it is
Timeout for logging in, which closes such a connection after 60 seconds by default, and
Max. non-HTTP connections to site, which counts every open connection including unauthenticated
ones. Lower the login timeout before you touch the auto-ban settings. For blocking a specific source
outright, see
Restricting access to CompleteFTP by IP address.
4. A disk-usage quota over a large or busy folder. (B, and A on a heavily loaded server) Giving a user a quota under Quotas and Limits → Disk usage (MB) makes your CompleteFTP server attach a size watcher to each folder that user owns while a session is open. On Windows that is a file-system watcher plus a recursive size calculation, recomputed a few seconds after every change inside the tree. Over a directory with a very large number of files, or one being written to continuously, this is significant sustained work per session. Remove the quota from the affected users and see whether responsiveness returns before investigating anything else. Users with no quota set attach no watchers at all.
5. Per-user speed limits under load. (B) Download (kB/s) and Upload (kB/s) are enforced by
making the transfer wait, and the wait occupies the thread handling that session. A few limited users
cost nothing noticeable; many simultaneously limited users mean many simultaneously waiting threads.
If a hang correlates with peak concurrency and speed limits are widely applied, remove them from a
subset and re-test.
6. Your CompleteFTP server is a gateway. (A, B) In gateway configurations the log tag carries a
Gateway.{n} suffix, and the connection those lines describe is your CompleteFTP server acting as a
client of the upstream server. Memory and connection pressure there is driven by the upstream
protocol: over FTP a separate data connection is opened for every directory listing and every file
transfer, by design, so a workload of many small files produces many short-lived upstream connections
and ports. Count them on the upstream server before concluding the gateway is leaking.
7. Debug logging left on permanently. (A, B) Debug is what you need to diagnose this, and it writes a great deal more to disk. Turn it back down once you have the log you came for. See How to enable debug logging in CompleteFTP for the production trade-offs and rollover settings.
8. send failed: socket closed everywhere, and no memory error. (A) This is logged when your
CompleteFTP server tries to write to a connection the connecting client has already dropped without
completing the SSH close sequence. Some clients do this routinely at the end of every transfer. On its
own it is noise, not a fault, and it is not evidence of a memory problem. The same is true of
Connection abruptly closed: An established connection was aborted by the software in your host machine.
9. The log is silent across the whole incident. (B) No errors, no new session numbers, nothing.
Then the connections are not reaching your CompleteFTP server: look at the firewall, the load
balancer, and whether another process has taken the port. ERROR Server Unhandled exception in server
is the only line that indicates a failure inside your CompleteFTP server that nothing caught, and
its absence is informative.
10. Transfers stall and the log shows a window-space timeout instead. (A) That is a different failure with a different remedy; see ConsumeWindowSpace timed out in CompleteFTP and edtFTP.
Reading the output
Where the files are. On Windows,
C:\ProgramData\Enterprise Distributed Technologies\Complete FTP\Logs. On Linux,
/var/log/completeftp. Diagnostics.log carries everything at the configured level;
Errors.log carries warnings and above and is much smaller, which makes it the faster place to
confirm that an incident happened and the wrong place to diagnose it, because it does not contain
the surrounding session activity.
How an exception is written. The message and the exception occupy consecutive lines, and only the first carries the timestamp, level, logger and session tag:
2026-08-03 09:14:19,882 ERROR SFTPConnection [Session.481197:Default Site.22:jdoe:10.4.11.60] Exception thrown in packet processing: server error: check server log at 2026-08-03 09:14:19,882
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at ...
Searching for the exception type alone finds the second line and loses the session tag, the timestamp and the operation. Search for the message, then read down.
What the connecting client sees. When packet processing throws, your CompleteFTP server
disconnects that session with SSH disconnect reason 2 (protocol error) and the text
server error: check server log at <timestamp>. The user reports a protocol error or a corrupt-MAC
error from their client, which reads as a client-side or network fault and is neither: the timestamp
in that message is the one to look up in Diagnostics.log. Clients that report Corrupt Mac on input
or an incorrect MAC at the same moment as an out-of-memory exception on your CompleteFTP server are
seeing the truncated response, not a cipher problem.
What your CompleteFTP server reports about its own memory. Two Debug-level lines, and no others:
DEBUG MemoryUsage [Session.481240:Default Site.22:jdoe:10.4.11.60] Working set = 128.44 MB
DEBUG SSHServerChannel [Session.481240:Default Site.22:jdoe:10.4.11.60] Channel 0: Total memory use = 134217728 bytes
The first is the whole process's working set, emitted on each login and logout. It is the same quantity as Task Manager's working set on Windows and as resident set size on Linux, so it lines up with the figure recorded in step 1 by either route. The second is the managed heap, emitted every 500 SFTP data messages on a channel, so it only appears during active transfers.
There is no memory alarm to switch on. The Monitoring panel's Performance tab plots
connections, logins, failed logins, filter and auto-ban blocks, files and bytes transferred. Memory is
not among them, and email notifications are driven by file events rather than by server health. To be
warned before the machine fills, point whatever monitoring already covers the host at the working set
of CompleteFTPService.exe on Windows, or at the resident set of the completeftp.dll process on
Linux.
If you are on an older release
Upgrade. These were fixed and the fix is only in the release named.
| Symptom | Affected | Fixed in |
|---|---|---|
| Memory leak in the file server | 11.0.3, 11.0.4 | 11.0.5 |
| High memory use downloading large files over SFTP | up to 12.0.x | 12.1.0 |
| Memory leak when a custom command is called from a process trigger | up to 12.1.4 | 12.1.5 |
| General SFTP memory management | 13.0.0 | 13.0.1 |
| TLS session memory leak | up to 23.0.3 | 23.0.4 |
| FTPS memory management | up to 25.0.4 | 25.0.5 |
| 32-bit service process, capped near 2 GB whatever the machine had | before 22.0.0 | 22.0.0 |
Related
- Guide: Limits and Timeouts, which documents every field in the limits table in the product's own words.
- Guide: Performance, on what governs throughput and how to simulate your load.
- Guide: Monitoring and Log files, for the Monitoring panel and the log format.
- Guide: How to set quotas, to read before you apply a disk or speed quota.
- Guide: CLI reference and the Windows admin CLI. The admin CLI is off
by default on Windows and must be enabled before
completeftp monitorwill connect. - KB: How to enable debug logging in CompleteFTP.
- KB: Restricting access to CompleteFTP by IP address.
- KB: ConsumeWindowSpace timed out in CompleteFTP and edtFTP.
- KB: CompleteFTP service fails to start after an upgrade, for a service that is genuinely not running rather than unresponsive.
- Background on sizing and high availability: SFTP server, SFTP high availability.
- If none of the above resolves it, contact support with the zipped
Diagnostics.logcovering the incident, captured at Debug level, and the working-set figure from step 1.
Other technical articles
- CompleteFTP service fails to start after an upgrade: how to find the cause and fix it
- Does edtFTPnet/PRO support .NET 8? Which assembly to reference for .NET Framework, .NET Core and .NET 5+
- How to disable weak ciphers and encryption algorithms in CompleteFTP
- How to enable Debug logging in CompleteFTP for troubleshooting
- How to export and import CompleteFTP configuration between servers and versions
- IP filtering and whitelisting in CompleteFTP: what it supports and how to configure it
- Passive FTP and FTPS data connection failures in CompleteFTP: login works, the directory listing times out
- SFTP login fails with "No supported authentication methods available (server sent: publickey)" or "Permission denied (publickey)"
- Using Active Directory, Entra ID (Azure AD), SAML and LDAP groups to control who can log in to CompleteFTP
- Why SFTP transfers fail with "ConsumeWindowSpace timed out", and how to fix it
- Why an SSL certificate won't import into CompleteFTP, and how to fix it