0.57 Upgrade Guide

An upgrade guide that addresses breaking changes in 0.57.0

by

Vector breaking changes

  1. Environment variable interpolation disabled by default
  2. Template confinement for sink routing templates

Vector upgrade guide

Environment variable interpolation disabled by default

Environment variable interpolation in configuration files is now disabled by default. Previously, Vector automatically interpolated ${VAR} references found in config files.

The --disable-env-var-interpolation flag and VECTOR_DISABLE_ENV_VAR_INTERPOLATION environment variable have also been removed and should no longer be used.

Action needed

If your configuration relies on ${VAR} interpolation, pass --dangerously-allow-env-var-interpolation or set VECTOR_DANGEROUSLY_ALLOW_ENV_VAR_INTERPOLATION=true to restore the previous behavior:

Old (interpolation was on by default)
vector --config vector.yaml
New
vector --config vector.yaml --dangerously-allow-env-var-interpolation

Template confinement for sink routing templates

Sinks that accept {{ field }} references in routing templates (for example, object keys, file paths, HTTP headers, or table/stream names) now enforce a confinement boundary: the rendered value must stay within the literal prefix declared in the template. Templates with no literal prefix (e.g. key_prefix: "{{ host }}/") are rejected at startup. The file sink is the only exception: its base_dir config field can provide an explicit confinement root for path templates with no usable literal prefix.

This affects the following sinks: aws_s3, azure_blob, gcp_cloud_storage, webhdfs, file, elasticsearch, kafka, http, axiom, opentelemetry, splunk_hec_logs, splunk_hec_metrics, humio_logs, humio_metrics, loki, clickhouse, doris, redis, amqp, pulsar, mqtt, nats, greptimedb_logs, aws_cloudwatch_logs, gcp_stackdriver_logs, and prometheus_remote_write.

HTTP-family sinks have additional restrictions on URI and header templates to prevent request smuggling.

Watch the component_errors_total{error_type="confinement_failed"} metric after upgrading; it increments (and the offending event is dropped) whenever a rendered template value falls outside its confinement boundary at runtime.

You can restore the previous unconfined behavior by setting dangerously_allow_unconfined_template_resolution: true, which also sets the vector_security_confinement_disabled{component_type=...} metric to 1.

Action needed (file sink)

For the file sink, set the new base_dir config field to define the confinement root explicitly:

Old (file sink)
sinks:
  my_file:
    type: file
    path: "{{ host }}/log.txt"
New (file sink)
sinks:
  my_file:
    type: file
    path: "{{ host }}/log.txt"
    base_dir: "/var/log/vector"

This will prevent writes outside /var/log/vector.

If you want to rely on previous behavior, which is susceptible to file traversal injection attacks like .host = "../../../etc/shadow", you may also add the dangerously_allow_unconfined_template_resolution parameter.

Old (file sink)
sinks:
  my_file:
    type: file
    path: "{{ host }}/log.txt"
New (file sink)
sinks:
  my_file:
    type: file
    path: "{{ host }}/log.txt"
    dangerously_allow_unconfined_template_resolution: true

Action needed (all affected sinks)

For all affected sinks, you can add a static prefix directly to the template instead. For example, for the aws_s3 sink:

Old
sinks:
  my_s3:
    type: aws_s3
    bucket: my-bucket
    key_prefix: "{{ host }}/"
New
sinks:
  my_s3:
    type: aws_s3
    bucket: my-bucket
    key_prefix: "logs/{{ host }}/"

But if you want to rely on the unconfined template resolution and accept all risks that may come from using that you may also set the dangerously_allow_unconfined_template_resolution parameter.

Old
sinks:
  my_s3:
    type: aws_s3
    bucket: my-bucket
    key_prefix: "{{ host }}/"
New
sinks:
  my_s3:
    type: aws_s3
    bucket: my-bucket
    key_prefix: "{{ host }}/"
    dangerously_allow_unconfined_template_resolution: true