argoproj/argo-workflows · error

cannot use instance ID with Argo Server

Error message

cannot use instance ID with Argo Server

What it means

NewClientFromOptsWithContext rejects Opts that combine an Argo Server URL (opts.ArgoServerOpts.URL) with an instance ID. Instance-ID filtering is implemented server-side by the argo-server; when going through the server the client must not set one separately, so the combination is treated as a configuration contradiction and returns an error (note: returns nil client, nil error wrapper — check for the error before use).

Source

Thrown at pkg/apiclient/apiclient.go:73

	log := logging.GetLoggerFromContextOrNil(ctx)
	if log == nil {
		logLevel, err := logging.ParseLevelOr(opts.LogLevel, logging.Info)
		if err != nil {
			return nil, nil, err
		}
		logFormat, err := logging.TypeFromStringOr(opts.LogFormat, logging.Text)
		if err != nil {
			return nil, nil, err
		}
		log = logging.NewSlogLogger(logLevel, logFormat)
		ctx = logging.WithLogger(ctx, log)
	}
	log.WithField("opts", opts).Debug(ctx, "Client options")
	if opts.Offline {
		return newOfflineClient(ctx, opts.OfflineFiles)
	}
	if opts.ArgoServerOpts.URL != "" && opts.InstanceID != "" {
		return nil, nil, fmt.Errorf("cannot use instance ID with Argo Server")
	}
	switch {
	case opts.ArgoServerOpts.HTTP1:
		if opts.AuthSupplier == nil {
			return nil, nil, fmt.Errorf("AuthSupplier cannot be empty when connecting to Argo Server")
		}
		return newHTTP1Client(ctx, opts.ArgoServerOpts, opts.AuthSupplier(), opts.Proxy)
	case opts.ArgoServerOpts.URL != "":
		if opts.AuthSupplier == nil {
			return nil, nil, fmt.Errorf("AuthSupplier cannot be empty when connecting to Argo Server")
		}
		return newArgoServerClient(ctx, opts.ArgoServerOpts, opts.AuthSupplier())
	default:
		if opts.ClientConfigSupplier != nil {
			opts.ClientConfig = opts.ClientConfigSupplier()
		}
		return newArgoKubeClient(ctx, opts.ArgoKubeOpts, opts.ClientConfig, instanceid.NewService(opts.InstanceID))
	}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Remove the InstanceID from Opts when connecting through the Argo Server (the server applies its own instance ID)
  2. Unset the ARGO_INSTANCEID env var for CLI/server-based access, or drop --argo-server to use direct-kube access where an instance ID is valid
  3. Set the instance ID on the server (server --instanceid) instead of the client

Example fix

// before
client, err := apiclient.NewAPIClient(ctx, apiclient.Opts{ArgoServerOpts: apiclient.ArgoServerOpts{URL: url}, InstanceID: "x"})
// after
client, err := apiclient.NewAPIClient(ctx, apiclient.Opts{ArgoServerOpts: apiclient.ArgoServerOpts{URL: url}})
Defensive patterns

Strategy: validation

Validate before calling

func buildOpts(serverURL, instanceID string) (apiclient.Opts, error) {
    if serverURL != "" && instanceID != "" {
        return apiclient.Opts{}, errors.New("InstanceID is controller-side; do not combine with ArgoServerOpts.URL")
    }
    return apiclient.Opts{ArgoServerOpts: apiclient.ArgoServerOpts{URL: serverURL}, InstanceID: instanceID}, nil
}

Prevention

When it happens

Trigger: Creating an API client via apiclient.NewAPIClient / NewClientFromOptsWithContext with Opts{ArgoServerOpts: {URL: "https://argo.example:2746"}, InstanceID: "my-instance"} — e.g. running the argo CLI with both --argo-server and an ARGO_INSTANCEID env var set.

Common situations: CI environments where ARGO_INSTANCEID is exported globally for the controller while a script also points at the Argo Server; mixing flags --instanceid with --argo-server on the CLI; copying example code that sets both.

Related errors


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