Skip to content

Squid aborts with "FATAL: http_port: IPv6 is not available" on runners with IPv6 disabled on the Docker daemon #2139

Description

@Rubyj

Problem

awf-squid fails to start with a fatal error on any Docker host whose daemon has ipv6: false (the default on vanilla Docker installs). Config parsing aborts before any log file is opened, so the only evidence is in docker logs awf-squid before AWF's cleanup removes the container.

Full docker logs awf-squid stderr:

2026/04/21 15:53:16| WARNING: BCP 177 violation. Detected non-functional IPv6 loopback.
2026/04/21 15:53:16| aclIpParseIpData: IPv6 has not been enabled.
2026/04/21 15:53:16| aclIpParseIpData: IPv6 has not been enabled.
2026/04/21 15:53:16| aclIpParseIpData: IPv6 has not been enabled.
2026/04/21 15:53:16| Processing Configuration File: /etc/squid/squid.conf (depth 0)
2026/04/21 15:53:16| FATAL: http_port: IPv6 is not available.
2026/04/21 15:53:16| Not currently OK to rewrite swap log.
2026/04/21 15:53:16| storeDirWriteCleanLogs: Operation aborted.
2026/04/21 15:53:16| FATAL: Bungled /etc/squid/squid.conf line 74: http_port [::]:3128
2026/04/21 15:53:16| Squid Cache (Version 6.13): Terminated abnormally.

Line 74 is http_port [::]:3128, which was added in #1544 as dual-stack defense-in-depth for #1543.

The agent container then fails the dependency healthcheck with dependency failed to start: container awf-squid exited (1), and the whole gh-aw run fails at Execute Codex CLI (exit 1). Timeline from docker inspect:

StartedAt:  2026-04-21T15:53:16.126925664Z
FinishedAt: 2026-04-21T15:53:16.141058894Z   # ~15ms lifetime
ExitCode:   1
OOMKilled:  false

Root cause

Why Squid rejects http_port [::]:3128

Docker daemons default to ipv6: false. When that's set, Docker applies sysctl net.ipv6.conf.all.disable_ipv6=1 to every container's network namespace, including awf-squid's. Squid 6.13's startup probe of AF_INET6 then fails, and Squid treats http_port [::]:3128 as FATAL (not a warning, no fallback to IPv4-only listening) during config parse — before opening log files.

Why this is an undocumented implicit requirement

The http_port [::]:3128 line is emitted unconditionally by src/squid-config.ts:

// Listen on both IPv4 and IPv6 as defense-in-depth (see #1543)
let portConfig = `http_port ${port}\nhttp_port [::]:${port}`;

and in the SSL-bump path:

// Listen on both IPv4 and IPv6 as defense-in-depth (see: gh-aw-firewall issue #1543)
http_port 3128 ssl-bump ...
http_port [::]:3128 ssl-bump ...

Nothing in docs/architecture.md, docs/compatibility.md, or docs/troubleshooting.md documents the implicit "Docker daemon must have IPv6 enabled" requirement this creates. docs/compatibility.md lists "Docker Engine 20.10+" without noting that ipv6: true is required on the daemon config.

Per the fix analysis in #1543: "Fix 2 … However, Fix 1 alone should be sufficient since there's no reason for IPv6 in the isolated container network." So the listener is strictly defense-in-depth on top of the agent-side IPv6-disable work done in PR #1544 — but it's currently preventing a whole class of self-hosted runner users from running AWF at all.

Reproduction

  1. Provision a Linux host with a default Docker daemon (no "ipv6": true in /etc/docker/daemon.json). Reproduced on Amazon Linux 2023 / m7i-flex.2xlarge EC2 instance, Docker Engine installed via dnf install docker.

  2. Register as a self-hosted GitHub Actions runner.

  3. Run any gh-aw workflow with sandbox.agent: awf (the default). Minimal example:

    ---
    on:
      pull_request:
    runs-on: [self-hosted, your-label]
    engine:
      id: codex
    network:
      allowed: [defaults]
    ---
    Say hello.
  4. gh aw compile && git push → observe the agent job fail at Execute Codex CLI with the stderr above.

Workaround

Enable IPv6 on the Docker daemon. Add to /etc/docker/daemon.json:

{
  "ipv6": true,
  "fixed-cidr-v6": "fd00:d0c::/64"
}

…then systemctl restart docker. This prevents Docker from injecting net.ipv6.conf.all.disable_ipv6=1 into container namespaces, which allows Squid to bind [::]:3128. The AWF agent-namespace IPv6 disable from PR #1544 is orthogonal and continues to work — the agent container still has IPv6 disabled via sysctl after this change.

Proposed fixes (preferred → fallback)

  1. Make http_port [::]:… conditional. In the Squid entrypoint, probe whether IPv6 is available in the container namespace before appending the dual-stack listener:

    if [ "$(cat /proc/sys/net/ipv6/conf/all/disable_ipv6 2>/dev/null || echo 1)" = "0" ]; then
      # IPv6 available — keep http_port [::]:3128 for defense-in-depth
      :
    else
      # IPv6 disabled by Docker daemon — remove listener to avoid fatal startup error
      sed -i '/^http_port \[::\]:/d' /etc/squid/squid.conf
    fi
    exec squid -N -f /etc/squid/squid.conf

    Keeps the defense-in-depth intent on runners that have IPv6, while being resilient to the default case.

  2. Retry without the IPv6 listener on failure. Start Squid normally; if it exits with the IPv6 is not available FATAL, strip the [::]:… lines and restart. Slightly more complex but avoids a runtime sysctl probe.

  3. At minimum, document the requirement. Add an entry to docs/compatibility.md ("Docker daemon must be configured with ipv6: true"), and add the exact FATAL stderr and the daemon.json workaround to docs/troubleshooting.md so operators can find it via search.

Impact

  • Affected: any gh-aw workflow targeting a self-hosted runner whose Docker daemon is not explicitly configured with ipv6: true — the default on most Linux distros (Debian, Ubuntu, Amazon Linux, RHEL, etc.).
  • Severity: high for affected users — AWF cannot start at all. The only currently usable workaround is sandbox.agent: false, which the strict-mode compiler in v0.68.3 rejects unless strict: false is also set, effectively disabling the firewall entirely.
  • GitHub-hosted runners: not affected (their daemons have IPv6 enabled).

Environment

  • AWF container: ghcr.io/github/gh-aw-firewall/squid:0.25.20 (also agent:0.25.20, api-proxy:0.25.20)
  • gh-aw compiler: v0.68.3
  • Runner OS: Amazon Linux 2023
  • Docker: installed via dnf install docker (Docker CE 25.x, default daemon config — no /etc/docker/daemon.json)
  • Instance type: m7i-flex.2xlarge, self-hosted on AWS EC2
  • Architecture: x86_64

References

No activity

Activity on this issue will appear here.

Activity

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions