Skip to content

feat(config)!: parse configuration before interpolation - #26475

Open
pront wants to merge 6 commits into
masterfrom
pront-activate-parse-first
Open

pront wants to merge 6 commits into
masterfrom
pront-activate-parse-first

Conversation

@pront

@pront pront commented Sep 24, 2026

Copy link
Copy Markdown
Member

Summary

Finish the parse-first rollout using the helpers merged in #26441 and #26450. Configuration loading now parses YAML, TOML, or JSON before interpolating environment variables and secrets, then coerces values with the generated schema before deserialization. The HTTP provider uses the same loader.

Substituted quotes and newlines remain string content instead of changing the configuration structure. Environment interpolation remains opt-in. Comments and keys are no longer interpolated; TOML and JSON placeholders must be quoted, and values cannot expand into multiple array elements.

This enacts the structural-interpolation deprecation announced in 0.57.0 for removal in 0.59.0. Includes migration guidance and updated environment-variable and secrets documentation.

References

Vector configuration

With environment interpolation enabled, MY_COUNT=42 is converted to an integer:

sources:
  demo:
    type: demo_logs
    format: json
    count: "${MY_COUNT}"
sinks:
  output:
    type: console
    inputs: [demo]
    encoding:
      codec: json

How did you test this PR?

  • 99 configuration and HTTP-provider tests passed, covering YAML/TOML/JSON coercion, namespaced files, disabled interpolation, and secret retrieval.
  • make check-generated-docs: 248 component examples passed (4 skipped); no CUE or generated-example changes.
  • Full default/vendored binary smoke tests: multiline environment and file-secret values are emitted unchanged to a console sink.
  • Formatting, Markdown, changelog, and deprecation checks.
  • Scoped workspace Clippy passes with only the existing clippy::unused_async failure in unchanged src/test_util/http.rs:51 excluded.

Does this PR include user facing changes?

  • Yes. Breaking changelog and migration guidance included.
  • No. A maintainer will apply the no-changelog label to this PR.

Contributor Guidelines

  • Please read our Vector contributor resources.
  • Do not hesitate to use @vectordotdev/vector to reach out to us regarding this PR.
  • Before pushing, follow our pre-push guidance.
  • 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.

@pront
pront requested review from a team as code owners September 24, 2026 15:37
@github-actions github-actions Bot added meta: breaking change Anything that breaks backward compatibility. docs review on hold The documentation team reviews PRs only after a PR is approved by the COSE team. labels Sep 24, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T19:57:23.052963Z f6409b3 New commits
🔒 Security Review ✅ Completed 2026-10-09T19:53:52.781819Z f6409b3 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ecaeb9b7e1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/config/loading/config_builder.rs Outdated
Comment thread src/config/loading/loader.rs Outdated

@datadoghq-integration datadoghq-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bits Code Review: FAIL

Namespaced test files skip schema coercion. Directory fragments also merge before coercion, so valid interpolated scalar values can cause type errors.

Open Bits AI session

🤖 Bits Code Review · Commit ecaeb9b · @DataDog review to ask questions

Comment thread src/config/loading/config_builder.rs Outdated
Comment thread src/config/loading/loader.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f77daa9344

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

) -> Result<T, Vec<String>> {
deserialize_config_value(Value::Object(map))
let mut value = Value::Object(map);
coerce_config(&mut value)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve boolean-or-struct configuration shorthands

When a sink uses the supported shorthand healthcheck: false, this unconditional coercion rejects the boolean as ExpectedObject before serde can process it. SinkOuter::healthcheck explicitly uses deserialize_with = "bool_or_struct", whose visitor accepts either a boolean or a map, while its generated schema describes only the struct shape; the same pattern is used by many TLS and acknowledgement fields. Teach coercion about these alternate serde input shapes, or avoid schema-validating already typed non-string values, so previously valid configurations continue to load.

Useful? React with 👍 / 👎.

"what": "Environment-variable and secret placeholders in non-string positions",
"deprecated_since": "0.57.0",
"removed_in": "0.59.0",
"description": "Placeholders (`${VAR}` and `SECRET[backend.key]`) in structural positions of\na Vector configuration file are deprecated and will be removed in a future\nrelease. Current behavior is unchanged.\n\nAffected patterns:\n\n- Unquoted placeholders in non-string fields (`count = ${MY_COUNT}`).\n- Placeholders in map keys (`${KEY} = value`).\n- Placeholders in TOML table headers (`[${SECTION}]`).\n- Placeholders as inline array elements that expand to multiple values\n (`inputs = [${VECTOR_INPUTS}]` where `VECTOR_INPUTS=a,b`).\n\nMigration guidance will accompany the removal PR. `envsubst` can be used today\nto pre-expand env-var placeholders into a fully static config as a workaround.\n\nSee [RFC: parse-first config interpolation](https://github.com/vectordotdev/vector/blob/master/rfcs/2026-06-09-parse-first-config-interpolation.md)\nfor the full rationale."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Describe the enacted interpolation behavior

After moving this entry into deprecations_enacted with removed_in: 0.59.0, the copied description still says the feature “will be removed in a future release,” that current behavior is unchanged, and that migration guidance will arrive later. This directly contradicts both the enacted status and this commit's parse-first behavior, so the generated deprecations page gives upgrading users obsolete guidance; update the description to explain the behavior now in effect and point to the included migration steps.

Useful? React with 👍 / 👎.

pront added 2 commits October 9, 2026 12:32
Reuse parsed input snapshots for environment interpolation, secret discovery, and configuration assembly.

Preserve healthcheck, ASCII delimiter, directory merge, and metric tag compatibility, with regression tests and a released-binary comparison corpus.
@github-actions github-actions Bot added domain: external docs Anything related to Vector's external, public documentation domain: core Anything related to core crates i.e. vector-core, core-common, etc domain: vdev Anything related to the vdev tooling labels Oct 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f62338e9b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

) -> Result<T, Vec<String>> {
deserialize_config_value(Value::Object(map))
let mut value = Value::Object(map);
coerce_config(&mut value)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Support YAML integer spellings during schema coercion

When an interpolated YAML integer uses a valid YAML spelling such as 0x2, parse-first loading leaves the substituted value as a string and this new coercion pass rejects it because parse_integer accepts only decimal Rust integer syntax. Previously interpolation occurred before YAML parsing, so count: ${COUNT} with COUNT=0x2 produced the integer 2; the newly added environment-yaml-hex-integer compatibility case also explicitly expects this to remain accepted. Extend integer coercion to the scalar formats previously recognized by the configuration parser.

Useful? React with 👍 / 👎.

) -> Result<T, Vec<String>> {
deserialize_config_value(Value::Object(map))
let mut value = Value::Object(map);
coerce_config(&mut value)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve comma-separated no_proxy strings during coercion

When proxy.no_proxy is configured as a comma-separated scalar such as "localhost,127.0.0.1", this new coercion pass sees NoProxy's Vec<String> schema and wraps the scalar into ['localhost,127.0.0.1'] before deserialization. NoProxy intentionally gives these shapes different semantics: its string visitor splits on commas, while its sequence visitor treats each element as one pattern. The resulting configuration therefore contains one literal hostname with a comma and sends requests for both intended hosts through the proxy. Describe NoProxy as a string-or-array schema and preserve the matching input shape instead of wrapping it before serde.

Useful? React with 👍 / 👎.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs review on hold The documentation team reviews PRs only after a PR is approved by the COSE team. domain: core Anything related to core crates i.e. vector-core, core-common, etc domain: external docs Anything related to Vector's external, public documentation domain: vdev Anything related to the vdev tooling meta: breaking change Anything that breaks backward compatibility.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant