opnsense / opnsense/plugins

net/haproxy: boot path skips volatile runtime export; HAProxy starts manually after reboot

Open
#5,576 3 comments 0 reactions 1 assignee View on GitHub

@fraenki is already working on this.

Since Jul 29, 2026.

incomplete
Dominant language
PHP
Stars
1.2k
Forks
863
Avg merge
2d 6h
Merged PRs (30d)
10

Description

Important notices

  • I have read the contributing guidelines.
  • I have searched existing open and closed issues.
  • The title contains the affected plugin.

Plugin and system versions

  • Affected plugin: os-haproxy
  • Plugin version where first observed: 5.1
  • Last known working plugin version: Not known; no earlier version was tested in this environment.
  • OPNsense version: 26.7.1
  • HAProxy package: haproxy32 3.2.21

Exact GUI URL involved

https://<redacted-opnsense-host>/ui/haproxy/

Starting HAProxy from the service controls on this page after boot succeeds.

Describe the bug

After a reboot, HAProxy does not start automatically despite being enabled. The same configuration starts successfully from the HAProxy GUI after the system has completed booting.

This is reproducible with a generated HAProxy configuration that passes haproxy -c. It is not caused by a WebGUI listener conflict.

The observed start paths appear to differ:

  1. The normal rc.d boot service starts HAProxy from the persisted /usr/local/etc/haproxy.conf.
  2. The configuration refers to volatile runtime assets below /tmp/haproxy/ and /var/haproxy/.
  3. Those assets are created/exported by /usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh.
  4. The GUI/configd Start action works because it runs:
    setup.sh deploy
    rc-wrapper.sh start
    
  5. The package boot hook only calls setup/start when /usr/local/etc/haproxy.conf is absent:
    if [ ! -e /usr/local/etc/haproxy.conf -a -e /usr/local/etc/haproxy.conf.staging ]; then
        cp /usr/local/etc/haproxy.conf.staging /usr/local/etc/haproxy.conf
        /usr/local/etc/rc.d/haproxy start
    fi
    

Since /usr/local/etc/haproxy.conf persists across reboots, that branch is normally skipped. HAProxy is therefore started before its runtime certificate lists, certificate exports, Lua/map/error-file directories, and chroot preparation have been recreated.

Steps to reproduce

  1. Install and enable os-haproxy.
  2. Configure an HAProxy SSL frontend and enable automatic startup.
  3. Ensure the generated configuration contains runtime references such as:
    chroot /var/haproxy
    lua-prepend-path /tmp/haproxy/lua/?.lua
    crt-list /tmp/haproxy/ssl/<frontend-id>.certlist
    
  4. Confirm that HAProxy is running.
  5. Reboot OPNsense.
  6. After boot completes, check the service status: HAProxy is not running.
  7. Open https://<redacted-opnsense-host>/ui/haproxy/ and start HAProxy.
  8. HAProxy then starts successfully and listens as configured.

Expected behaviour

HAProxy should recreate its required volatile runtime assets and start automatically after boot.

Actual behaviour

HAProxy fails to start at boot, but starts successfully from the GUI after boot.

Additional technical details

HAProxy is enabled through /etc/rc.conf.d/haproxy:

haproxy_enable=YES
haproxy_setup="/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh"
haproxy_pidfile="/var/run/haproxy.pid"
haproxy_config="/usr/local/etc/haproxy.conf"

However, /usr/local/etc/rc.d/haproxy does not invoke $haproxy_setup; it performs a configuration check and starts HAProxy directly.

The GUI/configd action does invoke setup:

[start]
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/setup.sh deploy; /usr/local/opnsense/scripts/OPNsense/HAProxy/rc-wrapper.sh start

The normal OPNsense boot order also runs rc.bootup before ordinary rc.syshook start hooks. Consequently, the existing 50-haproxy start hook cannot prepare these files before the regular rc.d service start attempt.

Listener configuration

This is not the WebGUI HTTP redirect / listener-conflict case discussed in #5297:

  • WebGUI HTTPS uses port 4433.
  • WebGUI HTTP redirect is disabled.
  • HAProxy is intentionally configured to bind TCP ports 80 and 443.
  • After a manual GUI start, HAProxy successfully listens on TCP ports 80 and 443 for both IPv4 and IPv6.

Related issues

  • #4314 — similar “does not start after boot/reboot” symptom; automatically closed without a confirmed fix.
  • #5297 — similar title, but ultimately caused by a WebGUI listener conflict and does not apply here.

Suggested direction

Please consider making the boot path run the same preparation sequence as the GUI/configd Start action, or changing the HAProxy boot hook so it reliably prepares runtime assets before HAProxy is started.

A package-owned fix would be preferable to local startup-hook workarounds.

Contributor guide

Open the contributing guide

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.