What happened?
The builder image sets GOTOOLCHAIN=local, so xcaddy cannot fetch a newer Go toolchain. Any
Caddy module that declares a higher Go version than the image ships fails the documented custom
build, even though Go can resolve this by itself.
Today, on dunglas/frankenphp:1.12.7-builder-php8.5:
$ docker run --rm --entrypoint sh dunglas/frankenphp:1.12.7-builder-php8.5 \
-c 'go version; go env GOTOOLCHAIN'
go version go1.26.8 linux/amd64
local
Adding Mercure 1.0 to the recipe from docs/docker.md then fails:
go: downloading github.com/dunglas/mercure/caddy v1.0.2
go: github.com/dunglas/mercure/caddy@v1.0.2 requires go >= 1.27 (running go 1.26.8; GOTOOLCHAIN=local)
2026/09/27 06:29:14 [FATAL] exit status 1
Minimal reproduction, which is the documented recipe plus one --with:
FROM dunglas/frankenphp:1.12.7-builder-php8.5 AS builder
COPY --from=caddy:builder /usr/bin/xcaddy /usr/bin/xcaddy
RUN CGO_ENABLED=1 \
XCADDY_SETCAP=1 \
XCADDY_GO_BUILD_FLAGS="-ldflags='-w -s' -tags=nobadger,nomysql,nopgx" \
CGO_CFLAGS=$(php-config --includes) \
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
xcaddy build \
--output /usr/local/bin/frankenphp \
--with github.com/dunglas/frankenphp=./ \
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
--with github.com/dunglas/caddy-cbrotli \
--with github.com/dunglas/mercure/caddy@v1.0.2 \
--with github.com/dunglas/vulcain/caddy
Adding GOTOOLCHAIN=auto to that RUN makes it succeed. The resulting binary is correct:
$ frankenphp list-modules | grep mercure
http.handlers.mercure
Why this is worth a structural fix
This is the third report of the same failure, and the first two were resolved by raising the Go
version in the image:
Raising the version fixes the module that prompted it and leaves the next one broken. The pin is
what causes the recurrence: local tells Go to refuse the very mechanism that exists to resolve
this. The reporter of #1828 already identified GOTOOLCHAIN=auto as the workaround.
Two options, either of which ends the cycle:
- Set
GOTOOLCHAIN=go1.26+auto in the builder image. Builds keep using the shipped toolchain
and step up only when a module asks for more, so nothing is downloaded in the common case.
- Keep the pin and document it. Add
GOTOOLCHAIN=auto to the RUN in docs/docker.md, and say
that a module declaring a newer Go needs it.
Option 1 means the documented recipe keeps working when a dependency moves. Option 2 at least
turns a [FATAL] into something the docs predict.
I am happy to send a PR for either. Tell me which you prefer.
Build Type
Custom (tell us more in the description)
Worker Mode
Yes
Operating System
Linux
FrankenPHP version
1.12.7 (dunglas/frankenphp:1.12.7-builder-php8.5)
PHP version
8.5
What happened?
The builder image sets
GOTOOLCHAIN=local, soxcaddycannot fetch a newer Go toolchain. AnyCaddy module that declares a higher Go version than the image ships fails the documented custom
build, even though Go can resolve this by itself.
Today, on
dunglas/frankenphp:1.12.7-builder-php8.5:Adding Mercure 1.0 to the recipe from
docs/docker.mdthen fails:Minimal reproduction, which is the documented recipe plus one
--with:Adding
GOTOOLCHAIN=autoto thatRUNmakes it succeed. The resulting binary is correct:Why this is worth a structural fix
This is the third report of the same failure, and the first two were resolved by raising the Go
version in the image:
Raising the version fixes the module that prompted it and leaves the next one broken. The pin is
what causes the recurrence:
localtells Go to refuse the very mechanism that exists to resolvethis. The reporter of #1828 already identified
GOTOOLCHAIN=autoas the workaround.Two options, either of which ends the cycle:
GOTOOLCHAIN=go1.26+autoin the builder image. Builds keep using the shipped toolchainand step up only when a module asks for more, so nothing is downloaded in the common case.
GOTOOLCHAIN=autoto theRUNindocs/docker.md, and saythat a module declaring a newer Go needs it.
Option 1 means the documented recipe keeps working when a dependency moves. Option 2 at least
turns a
[FATAL]into something the docs predict.I am happy to send a PR for either. Tell me which you prefer.
Build Type
Custom (tell us more in the description)
Worker Mode
Yes
Operating System
Linux
FrankenPHP version
1.12.7 (
dunglas/frankenphp:1.12.7-builder-php8.5)PHP version
8.5