Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

HTTP/2 flow-control policies do not reload despite RECU_DYNAMIC

Closed
#13,694 0 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 2 days

@bneradt is already working on this.

Since Sep 15, 2026.

Assessment

This issue has not been assessed yet.

Description

Bug Config Reload Configuration HTTP/2
Problem

proxy.config.http2.flow_control.policy_in and policy_out are declared RECU_DYNAMIC and documented as :reloadable:, but HTTP/2 keeps the policy selected at process startup. traffic_ctl config set reports that a restart is not required, and config get reports the new value even though new connections still use the old policy.

Reproduction and observed behavior

I reproduced the inbound case in a local master-based build at 11e11c77e9 (the branch of #13447, based on 1e884fae05). Current master at 804e5e2dd1 still has the same policy initialization and record declarations. The relevant configuration is:

records:
  http2:
    initial_window_size_in: 65535
    max_concurrent_streams_in: 100
    flow_control:
      policy_in: 0
  1. Start ATS and open a fresh TLS/H2 connection. Send the HTTP/2 connection preface and an empty SETTINGS frame; record connection-level WINDOW_UPDATE increments.
  2. Run traffic_ctl config set proxy.config.http2.flow_control.policy_in 1. It says to wait for synchronization and that a restart is not required.
  3. Wait more than 10 seconds, confirm traffic_ctl config get proxy.config.http2.flow_control.policy_in returns 1, and repeat the probe on a new connection.
  4. Persist policy_in: 1 in records.yaml, restart ATS, and repeat the probe.
State Connection WINDOW_UPDATE increments Effective connection receive window
Started with policy 0 none 65,535
Runtime value reports 1 none 65,535
Restarted with policy 1 6,487,965 6,553,500

The restart control distinguishes this from existing connections retaining their original settings. I measured the inbound policy on the wire; the outbound policy uses the same defective initialization pattern described below.

Cause

In Http2::init(), each policy is read through a function-local uint32_t, then copied once to the static Http2FlowControlPolicy member:

uint32_t flow_control_policy_in_int = 0;
RecEstablishStaticConfigUInt32(flow_control_policy_in_int,
                             "proxy.config.http2.flow_control.policy_in");
// validation ...
flow_control_policy_in = static_cast<Http2FlowControlPolicy>(flow_control_policy_in_int);

RecEstablishStaticConfigUInt32 also registers RecLinkConfigUInt32 using the supplied variable's address. The callback therefore retains a pointer to a local variable whose lifetime ends when Http2::init() returns. It does not update the static enum used by HTTP/2. The outbound policy repeats this pattern.

Expected behavior

A configuration update should safely validate and update storage with sufficient lifetime, and new connections should use the new policy. If runtime policy changes are intentionally unsupported, the records and documentation should instead require a restart, without registering callbacks to local variables.

Persisting the value and restarting ATS is the current workaround.

Dominant language
C++
Stars
2k
Forks
878
Avg merge
3d 13h
Merged PRs (30d)
86

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from apache/trafficserver

All issues in apache/trafficserver

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.