From 21faf9c75abcf7d0ac4700ee550e05f716f1b714 Mon Sep 17 00:00:00 2001 From: majiayu000 <1835304752@qq.com> Date: Wed, 31 Dec 2025 02:34:19 +0800 Subject: [PATCH] fix: handle empty address in entrypoint redirection for socket activation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using socket activation, the entrypoint's address field may be empty since the listener is obtained from systemd rather than the configuration. This caused the redirection to fail with "missing port in address" error. This fix handles the case where the destination entrypoint's address is empty by returning an empty port, allowing the redirect middleware to use the scheme's default port (443 for https, 80 for http). Fixes #12469 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 Signed-off-by: majiayu000 <1835304752@qq.com> --- .../fixtures/redirection_empty_address.json | 30 +++++++++++++++++++ pkg/provider/traefik/internal.go | 9 +++++- pkg/provider/traefik/internal_test.go | 22 ++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 pkg/provider/traefik/fixtures/redirection_empty_address.json diff --git a/pkg/provider/traefik/fixtures/redirection_empty_address.json b/pkg/provider/traefik/fixtures/redirection_empty_address.json new file mode 100644 index 000000000..4547fe206 --- /dev/null +++ b/pkg/provider/traefik/fixtures/redirection_empty_address.json @@ -0,0 +1,30 @@ +{ + "http": { + "routers": { + "web-to-websecure": { + "entryPoints": [ + "web" + ], + "middlewares": [ + "redirect-web-to-websecure" + ], + "service": "noop@internal", + "rule": "HostRegexp(`^.+$`)", + "ruleSyntax": "default" + } + }, + "services": { + "noop": {} + }, + "middlewares": { + "redirect-web-to-websecure": { + "redirectScheme": { + "scheme": "https", + "permanent": true + } + } + } + }, + "tcp": {}, + "tls": {} +} diff --git a/pkg/provider/traefik/internal.go b/pkg/provider/traefik/internal.go index 7c99f977e..4d1f34a05 100644 --- a/pkg/provider/traefik/internal.go +++ b/pkg/provider/traefik/internal.go @@ -209,7 +209,14 @@ func (i *Provider) getEntryPointPort(name string, def *static.Redirections) (str return "", fmt.Errorf("'to' entry point field references a non-existing entry point: %s", def.EntryPoint.To) } - _, port, err := net.SplitHostPort(dst.GetAddress()) + address := dst.GetAddress() + if address == "" { + // When address is empty (e.g., socket activation), return empty port. + // The redirect middleware will use the scheme's default port. + return "", nil + } + + _, port, err := net.SplitHostPort(address) if err != nil { return "", fmt.Errorf("invalid entry point %q address %q: %w", name, i.staticCfg.EntryPoints[def.EntryPoint.To].Address, err) diff --git a/pkg/provider/traefik/internal_test.go b/pkg/provider/traefik/internal_test.go index e0697dd8d..42817a5f7 100644 --- a/pkg/provider/traefik/internal_test.go +++ b/pkg/provider/traefik/internal_test.go @@ -261,6 +261,28 @@ func Test_createConfiguration(t *testing.T) { }, }, }, + { + desc: "redirection_empty_address.json", + staticCfg: static.Configuration{ + EntryPoints: map[string]*static.EntryPoint{ + "web": { + Address: "", + HTTP: static.HTTPConfig{ + Redirections: &static.Redirections{ + EntryPoint: &static.RedirectEntryPoint{ + To: "websecure", + Scheme: "https", + Permanent: true, + }, + }, + }, + }, + "websecure": { + Address: "", + }, + }, + }, + }, } for _, test := range testCases {