plugin.yaml

The plugin.yaml file provides a YAML-based alternative to plugin.config for configuring global plugins available to Traffic Server. Global plugins are loaded at startup and have global effect on all transactions. This is in contrast to plugins specified in remap.config or remap.yaml, whose effects are limited to specific mapping rules.

Configuration File Fallback

Traffic Server will attempt to load plugin.yaml first. If this file is not found, it will fall back to loading plugin.config. If both files exist, only plugin.yaml will be used. This allows for a gradual migration from the legacy configuration format to YAML.

Format

The plugin.yaml file uses YAML syntax with a single required key:

  • plugins (required): A sequence of plugin entries.

Each plugin entry is a YAML mapping with the following fields:

path

Required. Path to the .so file. This path can be absolute or relative to the plugin directory (usually /usr/local/libexec/trafficserver).

enabled

Optional. Boolean. When set to false, the plugin is skipped entirely during startup — no dlopen, no TSPluginInit. The configuration entry remains in the file for easy re-enabling.

Default: true

params

Optional. A YAML sequence of string arguments passed to the plugin’s TSPluginInit function as argc/argv. Arguments that begin with $ designate Traffic Server configuration variables and will be expanded to their current value before the plugin is loaded.

config

Optional. Inline configuration content specified as a YAML scalar. The text is written to a temporary file at startup and the path is passed to the plugin as an argument, so existing plugins work without modification.

Tip

Use a literal block scalar (|) to preserve exact text including newlines and quoting – this is important for plugins like txn_box.so that assign special meaning to YAML quoting.

Note

Structured YAML (mappings or sequences) is rejected because re-serializing through a YAML emitter strips quoting semantics that some plugins depend on. For example, txn_box.so distinguishes "literal" (a quoted string) from extractor-name (an unquoted reference), and that distinction would be lost after a round-trip through YAML::Emitter. Supporting structured YAML may be revisited in the future.

load_order

Optional. Integer. Provides explicit control over the order in which plugins are loaded and therefore the order in which they are chained for request processing.

The loading rules are:

  1. Plugins with load_order are loaded first, sorted ascending by value (lowest number loads first).

  2. Among plugins with the same load_order value, their relative order in the YAML file is preserved (stable sort).

  3. Plugins without load_order are loaded after all ordered plugins, in the order they appear in the YAML file.

Most deployments do not need load_order — simply list plugins in the desired order in the YAML file. Use load_order when the file is managed by automation tools that may reorder entries, or when you want to guarantee a specific plugin loads first regardless of where it appears in the file.

Default: Unset (YAML sequence order).

Basic Structure

plugins:
  - path: stats_over_http.so

  - path: abuse.so
    params:
      - etc/trafficserver/abuse.config

  - path: header_rewrite.so
    params:
      - etc/trafficserver/header_rewrite.config

  - path: icx.so
    params:
      - etc/trafficserver/icx.config
      - $proxy.config.http.connect_attempts_timeout

  - path: experimental_plugin.so
    enabled: false
    params:
      - --verbose

Important

Loading order matters. Plugins are loaded in the order they appear in the YAML file, and this is the order in which they are chained for request processing (hooks are called in load order). If you need a plugin to run before another, place it earlier in the file or assign it a lower load_order value.

New Features Over plugin.config

plugin.yaml introduces several features not available in the legacy plugin.config format:

  • Disable without deleting — set enabled: false to skip a plugin without removing or commenting out the line.

  • Explicit load ordering — use load_order to control loading priority independent of file position.

  • Inline configuration — embed a plugin’s config content directly via the config field instead of maintaining a separate file.

  • Variable expansion$record references in params are expanded to their current value at load time (same as plugin.config).

  • Startup logging — each plugin produces a NOTE-level log line showing its load sequence number, path, and status.

  • Runtime introspectiontraffic_ctl plugin list shows the loaded plugins and their status via JSONRPC.

  • Automated migrationtraffic_ctl config convert plugin_config converts an existing plugin.config to plugin.yaml.

Examples

Disabling a Plugin

plugins:
  - path: debug_plugin.so
    enabled: false

The plugin entry remains in the configuration file but is not loaded. Set enabled: true (or remove the field) to re-enable it.

Plugin Loading Order

By default, plugins load in the order they appear in the YAML file — top to bottom. This is the same behavior as plugin.config and is sufficient for most deployments:

plugins:
  - path: certifier.so           # loads 1st
  - path: header_rewrite.so      # loads 2nd
  - path: stats_over_http.so     # loads 3rd

When load_order is set, it overrides the file order. Plugins with load_order always load before plugins without it:

plugins:
  - path: stats_over_http.so
    load_order: 300

  - path: certifier.so
    load_order: 100

  - path: header_rewrite.so
    load_order: 200

  - path: xdebug.so

Despite the YAML sequence order, the actual load order is:

  1. certifier.so (load_order: 100)

  2. header_rewrite.so (load_order: 200)

  3. stats_over_http.so (load_order: 300)

  4. xdebug.so (no load_order — loaded last, in file order)

Tip

Use gaps between load_order values (e.g. 100, 200, 300) so new plugins can be inserted later without renumbering.

Inline Configuration

The config field lets you embed a plugin’s configuration directly in plugin.yaml instead of maintaining a separate file. At startup, Traffic Server writes the content to a temporary file in the configuration directory and passes the path of that file to the plugin as an argument — exactly the same way a params entry pointing to an external file would work. The plugin reads the file as usual; it has no knowledge the content was inlined.

Use the YAML literal block scalar (|) to provide the content:

plugins:
  - path: header_rewrite.so
    config: |
      cond %{SEND_RESPONSE_HDR_HOOK}
         set-header X-Debug "true"

The text after | is preserved exactly (including newlines and indentation). It is written to a temporary file named after the plugin (e.g. <config_dir>/.header_rewrite_inline_1.conf). Temporary files from a previous run are removed automatically at startup.

This works equally well for plugins that read YAML configuration files. The block scalar preserves quoting and formatting that some YAML-consuming plugins rely on:

plugins:
  - path: txn_box.so
    config: |
      txn_box:
        when: proxy-rsp
        do:
          - proxy-rsp-field<X-TxnBox>: "inline-config-active"

Note

The config field and params can be used together. When both are present, the temporary file path is inserted before the params entries in the argument vector:

plugins:
  - path: header_rewrite.so
    config: |
      cond %{SEND_RESPONSE_HDR_HOOK}
        set-header X-Source "inline"
    params:
      - --verbose

The plugin receives argv = ["header_rewrite.so", "<config_dir>/.header_rewrite_inline_1.conf", "--verbose"].

The inline file path is always a bare positional argument at argv[1]. This works for plugins that take a config file as their first argument (e.g., header_rewrite.so, txn_box.so). Plugins that require a flag before the filename (e.g., --config <file>) should use params pointing to a separate file instead of config.

Configuration Variable Expansion

plugins:
  - path: icx.so
    params:
      - etc/trafficserver/icx.config
      - $proxy.config.http.connect_attempts_timeout

Arguments beginning with $ are expanded to the current value of the corresponding Traffic Server configuration variable before the plugin is loaded.

Migration from plugin.config

plugin.config

plugin.yaml

stats_over_http.so
plugins:
  - path: stats_over_http.so
abuse.so etc/trafficserver/abuse.config
plugins:
  - path: abuse.so
    params:
      - etc/trafficserver/abuse.config
icx.so etc/trafficserver/icx.config $proxy.config.http.connect_attempts_timeout
plugins:
  - path: icx.so
    params:
      - etc/trafficserver/icx.config
      - $proxy.config.http.connect_attempts_timeout
# header_rewrite.so etc/trafficserver/header_rewrite.config
plugins:
  - path: header_rewrite.so
    params:
      - etc/trafficserver/header_rewrite.config
    enabled: false

Startup Logging

When plugins are loaded from plugin.yaml, each plugin produces a NOTE-level log line showing its load sequence number, path, and status:

[NOTE] plugin #1 loading: certifier.so (load_order: 100)
[NOTE] plugin #2 loading: header_rewrite.so
[NOTE] plugin #3 skipped: experimental_plugin.so (enabled: false)

See Also

plugin.config, TSAPI(3ts), TSPluginInit(3ts), remap.config, remap.yaml