Skip to content

Conversation

@fclairamb
Copy link
Owner

Summary

When a client disconnects immediately after connecting (before sending any commands), the server would log multiple error messages that appear alarming but are actually normal FTP client behavior.

Problem

Some FTP clients (like KDE Dolphin, certain Go clients) may:

  • Open a probe connection and immediately close it
  • Disconnect before the server can read the first command

This resulted in error logs like:

level=error err="set tcp ...: use of closed network connection" event="Network error"
level=error err="read tcp ...: use of closed network connection" event="Network error"

Solution

Detect "use of closed network connection" and "connection reset by peer" errors and handle them as normal disconnects (debug level) instead of errors.

Changes in two code paths:

  1. readCommand(): Check if SetDeadline fails due to closed connection and return early
  2. handleCommandsStreamError(): Treat closed connection errors as normal disconnects

Before

level=error ... err="set tcp ... use of closed network connection" event="Network error"
level=error ... err="read tcp ... use of closed network connection" event="Network error"

After

level=debug ... event="Client disconnected before first command"

(Only visible when debug logging is enabled)

Test plan

  • All existing tests pass
  • go build ./... succeeds
  • Manual test with FTP client that exhibits this behavior

Fixes #710

🤖 Generated with Claude Code

When a client disconnects immediately after connecting (before sending
any commands), the server would log multiple error messages:
- "Network error" from SetDeadline
- "Network error" or "Read error" from ReadLine

This change detects "use of closed network connection" and "connection
reset by peer" errors and handles them as normal disconnects instead
of errors. This reduces log noise and provides clearer debugging info.

The fix addresses two code paths:
1. In readCommand(): Check if SetDeadline fails due to closed connection
   and return early instead of trying to read
2. In handleCommandsStreamError(): Treat closed connection errors as
   normal disconnects (debug level) instead of errors

Fixes #710

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Jan 11, 2026

Codecov Report

❌ Patch coverage is 50.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.73%. Comparing base (153f345) to head (2ad6aa6).

Files with missing lines Patch % Lines
client_handler.go 50.00% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #602      +/-   ##
==========================================
- Coverage   87.14%   86.73%   -0.41%     
==========================================
  Files          12       12              
  Lines        1828     1840      +12     
==========================================
+ Hits         1593     1596       +3     
- Misses        157      164       +7     
- Partials       78       80       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants