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
- Remove the InstanceID from Opts when connecting through the Argo Server (the server applies its own instance ID)
- 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
- 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
- Never export ARGO_INSTANCEID globally in environments that also use the Argo Server
- Set the instance ID on the server process, not the client
- Audit env vars in CI runners for ARGO_INSTANCEID before running argo CLI
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
- AuthSupplier cannot be empty when connecting to Argo Server
- failed to create request: %w
- InvalidArgument
- this is impossible if you are not using the Argo Server, see
- failure to create dynamic client: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/fd133ce5522d848e.
Report an issue: GitHub.