Skip to content

MQTT sink ignores tls.alpn_protocols and hardcodes ALPN to ["mqtt"] #25805

Description

@frank-hivewatch

A note for the community

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Problem

Vector's mqtt sink documents a tls.alpn_protocols option, and the config is accepted
without error. However, the value is silently ignored: the sink hardcodes the TLS ALPN
protocol list to ["mqtt"] when it builds the rumqttc transport, so whatever the user sets
in tls.alpn_protocols never reaches the TLS handshake.

In src/sinks/mqtt/config.rs (confirmed on the latest release v0.56.0 at line 141, and on master):

let alpn = Some(vec!["mqtt".into()]);
options.set_transport(Transport::Tls(TlsConfiguration::Simple {
    ca,
    client_auth,
    alpn,
}));

ca and client_auth are derived from the parsed TLS settings, but alpn is a literal — the
configured tls.alpn_protocols is not consulted.

Concrete impact: This makes the MQTT sink unable to connect to AWS IoT Core over port
443
. On its default endpoints, AWS IoT Core requires clients using X.509 client-certificate
authentication on port 443 to negotiate the ALPN protocol name x-amzn-mqtt-ca; the bare
mqtt ALPN name is only accepted for custom authentication, not X.509 mutual TLS.
(Reference: AWS IoT Core "Device communication protocols" — Protocols, port mappings, and
authentication table.) Because Vector forces mqtt, the handshake for an X.509 mutual-TLS
connection on 443 cannot complete. Port 443 is the only option for deployments behind
firewalls that block the non-standard MQTT port 8883.

Expected behavior: When tls.alpn_protocols is set, the MQTT sink should use it as the
ALPN protocol list in the TLS handshake (e.g. ["x-amzn-mqtt-ca"]), falling back to ["mqtt"]
only when the option is unset. Otherwise, tls.alpn_protocols should be rejected as
unsupported for this sink rather than silently accepted.

Configuration

sinks:
  iot_core:
    type: mqtt
    inputs: [events]
    host: "REDACTED-ats.iot.us-west-2.amazonaws.com"
    port: 443
    topic: "example/topic"
    encoding:
      codec: json
    tls:
      enabled: true
      ca_file: /etc/vector/AmazonRootCA1.pem
      crt_file: /etc/vector/thing-cert.pem
      key_file: /etc/vector/thing-key.pem
      server_name: "REDACTED-ats.iot.us-west-2.amazonaws.com"
      alpn_protocols: ["x-amzn-mqtt-ca"]   # accepted, documented — but ignored by the sink

Version

0.56.0

Debug Output

Connection to AWS IoT Core on port 443 fails to negotiate the required ALPN protocol; the sink
attempts the handshake with ALPN `mqtt` regardless of the configured `alpn_protocols`. (Full
`RUST_BACKTRACE=full vector -vvv` TLS handshake output can be attached / gisted.)

Example Data

N/A — the failure occurs at TLS/MQTT connection time, before any event is delivered.

Additional Context

  • The workaround options are limited: there is no supported way to change the ALPN from
    config, so firewalled sites that can only egress on 443 cannot use the MQTT sink against AWS
    IoT Core's default endpoints.
  • Same underlying rumqttc TlsConfiguration is used by the MQTT source, which likely
    has the same hardcoded-ALPN limitation and would benefit from the same fix.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions