argoproj/argo-workflows · error
oidc end-session endpoint must be an absolute HTTP(S) URL wi
Error message
oidc end-session endpoint must be an absolute HTTP(S) URL without user info or a fragment: %q
What it means
constructLogoutURL builds the OIDC provider end-session URL used during logout. If the configured end-session endpoint is non-empty but not an absolute HTTP(S) URL without userinfo/fragment, logout falls back to the plain redirect URL and returns this error. It ensures the server only redirects to well-formed provider endpoints.
Source
Thrown at server/logout/logout.go:66
}
func parseAbsoluteHTTPURL(rawURL string) (*url.URL, bool) {
parsedURL, err := url.Parse(rawURL)
if err != nil || parsedURL.Hostname() == "" || parsedURL.User != nil || parsedURL.Fragment != "" ||
(!strings.EqualFold(parsedURL.Scheme, "http") && !strings.EqualFold(parsedURL.Scheme, "https")) {
return nil, false
}
return parsedURL, true
}
func constructLogoutURL(logoutURL, clientID, redirectURL string) (string, error) {
if logoutURL == "" {
return redirectURL, nil
}
parsedURL, ok := parseAbsoluteHTTPURL(logoutURL)
if !ok {
return redirectURL, fmt.Errorf("oidc end-session endpoint must be an absolute HTTP(S) URL without user info or a fragment: %q", logoutURL)
}
query := parsedURL.Query()
if clientID != "" {
query.Set("client_id", clientID)
}
if redirectURL != "" {
query.Set("post_logout_redirect_uri", redirectURL)
}
parsedURL.RawQuery = query.Encode()
return parsedURL.String(), nil
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
w.Header().Set("Allow", http.MethodGet+", "+http.MethodHead)
w.WriteHeader(http.StatusMethodNotAllowed)
returnView on GitHub (pinned to 35bff19146)
Solutions
- Fix the OIDC end-session endpoint in the argo SSO configmap to a full https:// URL
- Verify the issuer metadata (.well-known/openid-configuration) publishes a valid absolute end_session_endpoint
- Remove any fragment or userinfo from the endpoint
Example fix
// before (argo-cm sso config) endSessionEndpoint: /oidc/logout // after endSessionEndpoint: https://sso.example.com/oidc/logout
Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(ssoCfg.EndSessionEndpoint)
if ssoCfg.EndSessionEndpoint != "" && (err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" || u.Fragment != "") {
return fmt.Errorf("invalid end-session endpoint: %q", ssoCfg.EndSessionEndpoint)
} Type guard
func isAbsoluteHTTPEndpoint(raw string) bool {
u, err := url.Parse(raw)
return err == nil && (u.Scheme == "http" || u.Scheme == "https") && u.Host != "" && u.Fragment == ""
} Try / catch
redirect, err := logout.ConstructLogoutURL(...)
if err != nil {
log.Printf("falling back to plain redirect: %v", err)
// redirect already contains the safe fallback URL
} Prevention
- Fetch end_session_endpoint from the issuer's discovery document rather than hardcoding
- Ping the provider's .well-known/openid-configuration after SSO config changes
- Avoid copying URLs with fragments from browser address bars
When it happens
Trigger: OIDC issuer discovery or explicit configuration yields an end_session_endpoint value that is empty-schemed, relative, contains userinfo, or has a fragment, and a user performs logout on the Argo UI.
Common situations: Misconfigured OIDC provider metadata, hand-written endSessionEndpoint in the SSO configmap with a typo, or an issuer URL missing its scheme.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- failed to load system cert pool: %w
- failed to append certificates from PEM string
- not implemented
- issuer empty
- clientID empty
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/2768f9967ac20411.
Report an issue: GitHub.