fluent/fluentd · error · ArgumentError
BUG: cannot create connection for UDP
Error message
BUG: cannot create connection for UDP
What it means
ArgumentError from server_create_connection. Connection-style servers are only possible for CONNECTION_PROTOCOLS = [:tcp, :tls, :unix]; UDP is datagram-based and has no per-connection lifecycle, so proto: :udp is rejected even though :udp is a valid protocol for the helper's datagram APIs.
Source
Thrown at lib/fluent/plugin_helper/server.rb:76
CONNECTION_PROTOCOLS = [:tcp, :tls, :unix]
# server_create_connection(:title, @port) do |conn|
# # on connection
# source_addr = conn.remote_host
# source_port = conn.remote_port
# conn.data do |data|
# # on data
# conn.write resp # ...
# conn.close
# end
# end
def server_create_connection(title, port, proto: nil, bind: '0.0.0.0', shared: true, backlog: nil, tls_options: nil, **socket_options, &block)
proto ||= (@transport_config && @transport_config.protocol == :tls) ? :tls : :tcp
raise ArgumentError, "BUG: title must be a symbol" unless title && title.is_a?(Symbol)
raise ArgumentError, "BUG: port must be an integer" unless port && port.is_a?(Integer)
raise ArgumentError, "BUG: invalid protocol name" unless PROTOCOLS.include?(proto)
raise ArgumentError, "BUG: cannot create connection for UDP" unless CONNECTION_PROTOCOLS.include?(proto)
raise ArgumentError, "BUG: tls_options is available only for tls" if tls_options && proto != :tls
raise ArgumentError, "BUG: block not specified which handles connection" unless block_given?
raise ArgumentError, "BUG: block must have just one argument" unless block.arity == 1
if proto == :tcp || proto == :tls
socket_options[:linger_timeout] ||= @transport_config&.linger_timeout || 0
end
socket_options[:receive_buffer_size] ||= @transport_config&.receive_buffer_size
socket_option_validate!(proto, **socket_options)
socket_option_setter = ->(sock){ socket_option_set(sock, **socket_options) }
case proto
when :tcp
server = server_create_for_tcp_connection(shared, bind, port, backlog, socket_option_setter, &block)View on GitHub (pinned to dd45c6e18d)
Solutions
- Use the datagram APIs instead: server_create(:my_udp, port: 5160, proto: :udp) { |data, sock| ... } or server_create_udp_service
- If connection semantics (connect/close/write per peer) are genuinely required, switch the design to proto: :tcp or :tls
Example fix
# before
server_create_connection(:my_udp, 5160, proto: :udp) do |conn|
...
end
# after
server_create(:my_udp, port: 5160, proto: :udp) do |data, sock|
sock.write("echo: #{data}")
end Defensive patterns
Strategy: type-guard
Validate before calling
raise ArgumentError, 'use server_create for udp' if proto == :udp
server_create_connection(title, port, proto: proto) { |conn| ... } Type guard
def connection_capable?(proto) %i[tcp tls unix].include?(proto) end # usage if connection_capable?(proto) server_create_connection(title, port, proto: proto, &block) else server_create(title, port: port, proto: proto, &datagram_block) end
Prevention
- Branch on protocol before choosing the server API: connection APIs for tcp/tls/unix, datagram APIs for udp
- Cover both branches in plugin tests
When it happens
Trigger: server_create_connection(:my_udp, 5160, proto: :udp) { |conn| ... } - the caller asks for a connection server over UDP.
Common situations: Plugin authors reusing a TCP connection template and flipping proto to :udp; misunderstanding that in_udp-style sources are datagram services, not connection servers.
Related errors
- BUG: invalid protocol name
- BUG: tls_options is available only for tls
- no valid cert options configured. specify either 'cert_path'
- <counter_client> is required in <system>
- @type is required in <format>
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/ec2ad06f92de1e72.
Report an issue: GitHub.