Skip to content

bug: shared Ingress Controller defaults differ across binaries, Helm charts, and docs #462

Open

Description

@kayx23

Problem

API7 Ingress Controller and Apache APISIX Ingress Controller share the same config.yaml structure, and the shared documentation presents one set of defaults. However, the two controller binaries and their two Helm charts currently produce different defaults for several non-provider fields.

Most users install the controllers through Helm, so these differences change effective behavior depending on the selected controller and installation path. We should choose canonical defaults for common fields, align the implementations where appropriate, and document any intentional installation-specific differences.

Scope and versions

This audit covers the active Ingress Controller 2.1.0 documentation and the releases that deploy controller 2.1.0:

  • Apache APISIX Ingress Controller 2.1.0
  • API7 Ingress Controller 2.1.0
  • Apache apisix-ingress-controller chart 1.2.x
  • API7 api7-ingress-controller chart 0.1.x

provider.type is intentionally excluded. listener_port_match_mode is APISIX-only and should remain explicitly documented as product-specific.

Default differences

Field APISIX binary API7 binary APISIX Helm API7 Helm
leader_election_id apisix-ingress-gateway-leader apisix-ingress-gateway-leader apisix-ingress-controller-leader apisix-ingress-controller-leader
leader_election.lease_duration 30s 30s Declares 15s, but effective value is 30s because the rendered key is ignored 15s
leader_election.renew_deadline 20s 20s Declares 10s, but effective value is 20s because the rendered key is ignored 10s
server_addr :9092 :9092 Not emitted; effective :9092 127.0.0.1:9092
provider.sync_period 1h 0 1m 1h
webhook.enable false false true true

The remaining literal values align, but some still have chart-control or documentation problems described below.

Additional findings

APISIX Helm renders invalid leader-election keys

The APISIX chart renders:

leader_election:
  leaseDuration: 15s
  renewDeadline: 10s
  retryPeriod: 2s

The controller accepts lease_duration, renew_deadline, and retry_period. It uses non-strict yaml.Unmarshal, so the camelCase keys are silently ignored. This means all three APISIX Helm overrides are ineffective. A focused upstream issue should track that chart defect.

Hidden Helm fallback values also drift

The chart templates contain fallback literals that differ from values.yaml:

  • APISIX: values.yaml uses 1m, while the template fallback is 1s.
  • API7: values.yaml uses 1h, while the template fallback is 0s.

Helm configuration surfaces differ

  • APISIX Helm does not expose or emit enable_server or server_addr.
  • Both charts hard-code the webhook certificate filename, key filename, and directory when the webhook is enabled.
  • API7 correctly omits listener_port_match_mode because the API7 binary does not support it.

Some differences may be intentional

Both binaries default the admission webhook to disabled, while both charts enable it and provision the required certificates and Kubernetes resources. This can be a valid installation-context override and should be documented as such rather than automatically copied into the raw binary default.

Changing leader_election_id also needs upgrade planning because replicas using different election IDs can participate in separate elections.

Related issue

Proposed acceptance criteria

  • Decide canonical values for every common divergent field.
  • Record any approved binary-versus-Helm differences, especially webhook.enable.
  • Align API7 controller defaults and sample configuration with the decisions.
  • Align API7 Helm values and template fallbacks with the decisions.
  • Track and cross-link the corresponding APISIX Helm changes.
  • Update the shared Ingress Controller configuration reference after the engineering decisions are implemented.
  • Correct the documentation for secure_metrics, sync_period, and init_sync_delay.
  • Add tests that render the default charts, load the resulting config.yaml through the real controller parser, reject unknown fields, and assert the effective defaults.
  • Add upgrade guidance if leader_election_id changes.

Evidence

Activity

  1. coderabbitai commented on Aug 17, 2026

    @coderabbitai
    🔗 Related PRs

    #419 - feat: support port-based routing for Gateway API routes [merged]
    #424 - feat: support downstream mTLS via Gateway API frontendValidation [closed]
    #430 - fix: rebuild the ADC baseline on leader acquisition [merged]
    #431 - feat: support Gateway API 1.6.0 [merged]
    #457 - fix: keep API7 synchronization active and correct defaults [open]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. kayx23 commented on Aug 17, 2026

    @kayx23
    ContributorAuthor

    Focused upstream APISIX Helm chart issue: apache/apisix-helm-chart#997

  3. changed the title [-]chore: align shared configuration defaults across API7, APISIX, and Helm[/-] [+]bug: shared Ingress Controller defaults differ across binaries, Helm charts, and docs[/+] on Aug 17, 2026
  4. kayx23 commented on Aug 26, 2026

    @kayx23
    ContributorAuthor

    2.2.0 follow-up: listener_port_match_mode exposes the same default-drift problem

    The original scope note that listener_port_match_mode is APISIX-only is no longer current. API7 added the setting in api7/api7-ingress-controller#419, and both 2.2.0 controller implementations now use off when the field is omitted.

    Effective released defaults

    Field APISIX binary 2.2.0 API7 binary 2.2.0 APISIX Helm 1.3.0 API7 Helm 0.1.26
    listener_port_match_mode off off auto off

    The APISIX umbrella chart 2.17.0 pins controller chart 1.3.0 and does not override this value, so its effective mode is also auto.

    How the difference arose

    1. apache/apisix-ingress-controller#2703 introduced auto, explicit, and off for HTTPRoute/GRPCRoute. The original contributor proposed auto as the 2.1.0 default to preserve the behavior introduced by that PR.
    2. During apache/apisix-ingress-controller#2804, review demonstrated the common failure case: a Gateway listener declares port 80, the Kubernetes Service maps it to APISIX port 9080, and auto injects server_port == 80, causing every route to miss. The maintainer changed the binary default to off so port-predicate injection became opt-in, and noted that the same change was applied to API7 feat: support port-based routing for Gateway API routes #419.
    3. apache/apisix-helm-chart#996 released controller 2.2.0, but the only values.yaml change was the image tag. The chart retained listenerPortMatchMode: auto; the PR body and review did not discuss the controller default change.
    4. api7/api7-helm-chart#353 explicitly exposed listenerPortMatchMode: off, describing it as matching the API7 controller default.

    This does not appear to be primarily a different-author problem. The same maintainer authored the controller default change, the APISIX Helm release, the API7 implementation, and the aligned API7 Helm release. The evidence points instead to a cross-repository release-sync gap. Preserving auto for existing Helm users may have been an unstated compatibility consideration, but neither #996 nor its reviews record that decision.

    User impact

    Both charts render this field explicitly into config.yaml. Therefore the chart value wins over the controller's omitted-field fallback:

    • APISIX Helm and APISIX umbrella-chart installations get auto unless users override it.
    • API7 Helm installations get off.
    • Running either binary with the field omitted gets off.

    Suggested follow-up

    • Extend apache/apisix-helm-chart#997, or open a focused issue, to decide whether APISIX chart 1.3.x should align with the controller's off default.
    • If the chart changes to off, include upgrade guidance for users who rely on auto to isolate routes by listener port.
    • If auto is intentionally retained for Helm compatibility, record that as an approved binary-versus-chart divergence.
    • Add a release check that renders each chart's default config.yaml, loads it through the real controller parser, and compares effective values with the binary defaults or an explicit divergence allowlist.
    • Update the shared configuration docs after the upstream decision. Until then, document the shipped effective values; the APISIX quickstart should set off explicitly for the common Service-port-to-container-port mapping.

    Relevant source paths:

    • apache/apisix-ingress-controller: internal/controller/config/config.go
    • apache/apisix-ingress-controller: internal/adc/translator/translator.go
    • apache/apisix-helm-chart: charts/apisix-ingress-controller/values.yaml
    • apache/apisix-helm-chart: charts/apisix-ingress-controller/templates/configmap.yaml
    • api7/api7-helm-chart: charts/ingress-controller/values.yaml
    • api7/api7-helm-chart: charts/ingress-controller/templates/configmap.yaml
  5. kayx23 commented on Aug 26, 2026

    @kayx23
    ContributorAuthor

    Focused upstream tracking is now separated from this umbrella audit:

    The PR aligns the dedicated APISIX Ingress Controller chart with the 2.2.0 binary default (off), adds upgrade guidance for users retaining auto, and adds rendered-config regression coverage. The APISIX umbrella dependency needs a follow-up bump after chart 1.3.1 is published.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions