argoproj/argo-workflows · error

additional headers must be colon(:)-separated: %s

Error message

additional headers must be colon(:)-separated: %s

What it means

parseHeaders converts strings like "Key:Value" into an http.Header by splitting on ":" and requiring an odd number of resulting segments (len%2==1) — i.e. exactly one colon separating key from value (values themselves may contain colons but not keys). If a header string doesn't match, it refuses with this error. It is used by the HTTP1 facade for extra headers passed to requests and event streams.

Source

Thrown at pkg/apiclient/http1/facade.go:218

	if r.StatusCode == http.StatusOK {
		return nil
	}
	x := &struct {
		Code    codes.Code `json:"code"`
		Message string     `json:"message"`
	}{}
	if err := json.NewDecoder(r.Body).Decode(x); err == nil {
		return status.Error(x.Code, x.Message)
	}
	return status.Error(codes.Internal, fmt.Sprintf(": %v", r))
}

func parseHeaders(headerStrings []string) (http.Header, error) {
	headers := http.Header{}
	for _, kv := range headerStrings {
		items := strings.Split(kv, ":")
		if len(items)%2 == 1 {
			return nil, fmt.Errorf("additional headers must be colon(:)-separated: %s", kv)
		}
		headers.Add(items[0], items[1])
	}
	return headers, nil
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Format each header as exactly "Name:Value" with one colon: --additional-header 'X-Foo:Bar'
  2. Repeat the flag once per header instead of combining them in one string
  3. Check shell quoting so the colon/value survive (quote the argument if it contains spaces or colons in the value)

Example fix

// before
--additional-header X-Trace-Id
// after
--additional-header X-Trace-Id:abc123
Defensive patterns

Strategy: validation

Validate before calling

func validateAdditionalHeaders(headers []string) error {
    for _, h := range headers {
        parts := strings.Split(h, ":")
        if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
            return fmt.Errorf("header %q must be exactly 'Name:Value'", h)
        }
    }
    return nil
}

Try / catch

headers := []string{"X-Trace-Id:abc"}
if err := validateAdditionalHeaders(headers); err != nil {
    return err
}
// pass to client; also wrap calls that use them:
if err != nil && strings.Contains(err.Error(), "colon(:)-separated") {
    return fmt.Errorf("check --additional-header format 'Name:Value': %w", err)
}

Prevention

When it happens

Trigger: Passing a header string to the HTTP1 client's additional-headers option (e.g. the CLI's --additional-header flag or h.headers in pkg/apiclient/http1) that contains no colon, more than one key-colon pair, or trailing whitespace forms like "Key:" with no value — e.g. --additional-header Authorization (missing ':token').

Common situations: Forgetting the value after the colon ("X-Trace-Id:"); putting the colon in the wrong place or quoting wrongly so the shell strips it; trying to pass multiple headers in one string instead of repeating the flag.

Related errors


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