argoproj/argo-workflows · error

protocol %s is not allowed

Error message

protocol %s is not allowed

What it means

ValidateProtocol checks that a UI link's URL protocol is in the allowedProtocol list, returning this error when slices.Contains does not find it. It is invoked from Sanitize for each entry in the config's Links, guarding against unsafe or unintended schemes in admin-configured links.

Source

Thrown at config/config.go:258

	return ResourceRateLimit{
		Limit: math.MaxFloat32,
		Burst: math.MaxInt32,
	}
}

func (c Config) GetPodGCDeleteDelayDuration() time.Duration {
	if c.PodGCDeleteDelayDuration == nil {
		return 5 * time.Second
	}

	return c.PodGCDeleteDelayDuration.Duration
}

func (c Config) ValidateProtocol(inputProtocol string, allowedProtocol []string) error {
	if slices.Contains(allowedProtocol, inputProtocol) {
		return nil
	}
	return fmt.Errorf("protocol %s is not allowed", inputProtocol)
}

func (c *Config) Sanitize(allowedProtocol []string) error {
	links := c.Links

	for _, link := range links {
		// We only validate user-supplied URL but not encode/decode it
		// see 2.4.2 on https://www.ietf.org/rfc/rfc2396.txt
		u, err := url.Parse(link.URL)
		if err != nil {
			return err
		}
		err = c.ValidateProtocol(u.Scheme, allowedProtocol)
		if err != nil {
			return err
		}
	}
	return nil

View on GitHub (pinned to 35bff19146)

Solutions

  1. Change the link URL in the configmap to use an allowed protocol (usually https).
  2. Add the desired protocol to `allowedLinkProtocol` in the workflow-controller-configmap and restart the controller.
  3. Check the failing link entry named in the Sanitize context for hidden characters or missing scheme.
  4. Read the controller logs to see which link triggered Sanitize failure and fix that specific entry.

Example fix

// before (configmap)
// links:
//   - name: Admin
//     url: http://internal.example.com
// after
// links:
//   - name: Admin
//     url: https://internal.example.com
Defensive patterns

Strategy: validation

Validate before calling

// before applying the configmap
links := cfg.Links
for _, l := range links {
    u, _ := url.Parse(l.URL)
    if !slices.Contains(allowedProtocols, u.Scheme) {
        return fmt.Errorf("link %q uses disallowed protocol %q", l.Name, u.Scheme)
    }
}

Type guard

func protocolAllowed(raw string, allowed []string) bool {
    u, err := url.Parse(raw)
    return err == nil && slices.Contains(allowed, u.Scheme)
}

Try / catch

if err := cfg.Sanitize(allowedProtocols); err != nil {
    return fmt.Errorf("controller config has a link with a disallowed protocol: %w", err)
}

Prevention

When it happens

Trigger: Config.Sanitize(allowedProtocol) encounters a c.Links entry whose URL scheme (e.g. http vs https, or javascript:) is not present in the allowed list passed by the controller config (`allowedLinkProtocol`).

Common situations: Admin adds a custom link using `http://` while only `https` is allowed; protocol list misconfigured or omitted in the controller configmap; upgrading Argo where stricter protocol validation was introduced.

Related errors


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