fluent/fluentd · error · ArgumentError

BUG: tls_options is available only for tls

Error message

BUG: tls_options is available only for tls

What it means

ArgumentError from server_create_connection. tls_options (cert/verify settings for the connection server) only apply when proto is :tls; passing them together with :tcp or :unix - including the implicit default, which is :tcp unless the plugin's <transport tls> is configured - is contradictory and rejected.

Source

Thrown at lib/fluent/plugin_helper/server.rb:78

      # 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)
        when :tls
          transport_config = if tls_options

View on GitHub (pinned to dd45c6e18d)

Solutions

  1. Set proto: :tls (or add <transport tls> so the default resolves to :tls) and keep the tls_options
  2. Remove tls_options when intentionally running plaintext :tcp/:unix
  3. Review whether the options belong in <transport tls> of the config instead of the API call

Example fix

# before
server_create_connection(:srv, 24224, proto: :tcp,
                         tls_options: {insecure: true}) { |conn| ... }

# after
server_create_connection(:srv, 24224, proto: :tls,
                         tls_options: {insecure: true}) { |conn| ... }
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'tls_options requires proto :tls' if tls_options && proto != :tls
server_create_connection(title, port, proto: proto, tls_options: tls_options) { |conn| ... }

Try / catch

begin
  server_create_connection(title, port, proto: proto, tls_options: tls_options, &block)
rescue ArgumentError => e
  raise ArgumentError, "#{e.message} (proto=#{proto.inspect}, tls_options=#{tls_options.inspect})"
end

Prevention

When it happens

Trigger: server_create_connection(:srv, 24224, proto: :tcp, tls_options: {insecure: true}), or tls_options passed without proto: while the transport config is tcp/plain.

Common situations: Copy-pasting a TLS server snippet and changing proto to :tcp but leaving tls_options; assuming the helper silently ignores irrelevant options; forgetting <transport tls> in the plugin config so the proto default stays :tcp while tls_options are given.

Understand the failure class

Related errors


AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21). Data as JSON: /api/errors/8ca7e60ea0baa692. Report an issue: GitHub.