Skip to content

feat(sources): add disconnect_mode option to tcp sources - #25331

Closed
tronboto wants to merge 2 commits into
vectordotdev:masterfrom
tronboto:disconnect-mode
Closed

feat(sources): add disconnect_mode option to tcp sources#25331
tronboto wants to merge 2 commits into
vectordotdev:masterfrom
tronboto:disconnect-mode

Conversation

@tronboto

Copy link
Copy Markdown
Contributor

Summary

Adds a disconnect_mode configuration option to TCP sources (socket, logstash, fluent, syslog, statsd) that controls how connections are closed on shutdown or when max_connection_duration_secs elapses.

The two modes are:

  • drain (default for socket, syslog, statsd) - sends a FIN and waits for the client to close. Existing behaviour.
  • abort (default for logstash, fluent) - sets SO_LINGER=0 to force close immediately with RST.

The original motivation is "write-only" clients such as Serilog.Sinks.Network that never read from the socket and therefore cannot detect a graceful shutdown. Additionally, the "reference implementations" for the beats (logstash) and fluent protocols also use an abort style shutdown:

This change also fixes a pre-existing bug where shutdown(SHUT_WR) would be called repeatedly on every loop iteration after max_connection_duration_secs elapsed, rather than just once. The kernel ignores subsequent calls but it's still wasteful.

Vector configuration

sources:
  tcp_in:
    type: socket
    mode: tcp
    address: "0.0.0.0:9000"
    shutdown_timeout_secs: 5
    disconnect_mode: abort
sinks:
  out:
    type: console
    inputs: [tcp_in]
    encoding.codec: text

How did you test this PR?

  • Manual testing with netcat and a write-only Python client against both modes, verifying FIN and RST behaviour using tcpdump.
  • A new unit test added to sources::socket:
    • tcp_disconnect_mode_abort_on_shutdown - verifies RST is received immediately on shutdown.

Change Type

  • New feature

Is this a breaking change?

  • Yes (default disconnect_mode for logstash and fluent changes from drain to abort)

Does this PR include user facing changes?

  • Yes - changelog fragment created

References

Closes #23855

Notes

  • Please read our Vector contributor resources.
  • Do not hesitate to use @vectordotdev/vector to reach out to us regarding this PR.
  • Some CI checks run only after we manually approve them.
    • We recommend adding a pre-push hook, please see this template.
    • Alternatively, we recommend running the following locally before pushing to the remote branch:
      • make fmt
      • make check-clippy (if there are failures it's possible some of them can be fixed with make clippy-fix)
      • make test
  • After a review is requested, please avoid force pushes to help us review incrementally.
    • Feel free to push as many commits as you want. They will be squashed into one before merging.
    • For example, you can run git merge origin master and git push.
  • If this PR introduces changes Vector dependencies (modifies Cargo.lock), please
    run make build-licenses to regenerate the license inventory and commit the changes (if any). More detail s on the dd-rust-license-tool.

@tronboto
tronboto requested a review from a team as a code owner April 30, 2026 08:19
@github-actions github-actions Bot added the domain: sources Anything related to the Vector's sources label Apr 30, 2026
@tronboto

Copy link
Copy Markdown
Contributor Author

@vectordotdev/vector would be grateful for some feedback on this when you get a chance, thanks.

@@ -0,0 +1,3 @@
Added a `disconnect_mode` configuration option to the `socket` (TCP mode), `logstash`, `fluent`, `syslog` (TCP mode), and `statsd` (TCP mode) sources. This controls how Vector closes TCP connections on shutdown or when `max_connection_duration_secs` elapses. The `drain` mode maintains the existing graceful shutdown behaviour while the `abort` mode closes connections immediately without waiting for the client to acknowledge the shutdown. This is useful for clients that never read from the socket and therefore cannot detect a graceful shutdown. The `logstash` and `fluent` sources default to `abort` to match the behaviour of Logstash's own Beats input plugin and Fluentd's `in_forward` plugin respectively.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR frames this as a breaking change so this changelog should also be breaking.md.

More importantly I think we cannot go ahead with this PR as is:

  • We can extract the shutdown(SHUT_WR) fix into an independent PR.
  • Maybe we can go ahead with the new disconnect_mode if the default for all affected components is drain to preserve existing behavior.
  • Optional but breaking change in a future PR: flip logstash/fluent defaults from drain to abort to match upstream Logstash/Fluentd

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pront . That all makes sense. Will try and find some time to look at these this week.

@pront pront added the type: feature A value-adding code addition that introduce new functionality. label Jul 13, 2026
@tronboto

Copy link
Copy Markdown
Contributor Author

@tronboto tronboto closed this Aug 12, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

domain: sources Anything related to the Vector's sources type: feature A value-adding code addition that introduce new functionality.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Socket source doesn't reset connection after shutdown_timeout_secs

2 participants