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)
		return

View on GitHub (pinned to 35bff19146)

Solutions

  1. Fix the OIDC end-session endpoint in the argo SSO configmap to a full https:// URL
  2. Verify the issuer metadata (.well-known/openid-configuration) publishes a valid absolute end_session_endpoint
  3. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/2768f9967ac20411. Report an issue: GitHub.