k3s-io/k3s · error
invalid flag use; cannot use --disable-etcd with --datastore
Error message
invalid flag use; cannot use --disable-etcd with --datastore-endpoint
What it means
--disable-etcd marks a server that joins an embedded-etcd cluster through a peer via --server, while --datastore-endpoint selects an external datastore. Setting both leaves the node with two contradictory data-plane instructions, so startup fails fast.
Source
Thrown at pkg/cli/server/server.go:266
serverConfig.ControlConfig.ClusterReset = cfg.ClusterReset
serverConfig.ControlConfig.ClusterResetRestorePath = cfg.ClusterResetRestorePath
serverConfig.ControlConfig.SystemDefaultRegistry = cfg.SystemDefaultRegistry
if serverConfig.ControlConfig.SupervisorPort == 0 {
serverConfig.ControlConfig.SupervisorPort = serverConfig.ControlConfig.HTTPSPort
}
if serverConfig.ControlConfig.DisableETCD && serverConfig.ControlConfig.JoinURL == "" {
return errors.New("invalid flag use; --server is required with --disable-etcd")
}
if serverConfig.ControlConfig.Datastore.Endpoint != "" && serverConfig.ControlConfig.DisableAPIServer {
return errors.New("invalid flag use; cannot use --disable-apiserver with --datastore-endpoint")
}
if serverConfig.ControlConfig.Datastore.Endpoint != "" && serverConfig.ControlConfig.DisableETCD {
return errors.New("invalid flag use; cannot use --disable-etcd with --datastore-endpoint")
}
if serverConfig.ControlConfig.DisableAPIServer {
// Servers without a local apiserver need to connect to the apiserver via the proxy load-balancer.
serverConfig.ControlConfig.APIServerPort = cmds.AgentConfig.LBServerPort
// If the supervisor and externally-facing apiserver are not on the same port, the proxy will
// have a separate load-balancer for the apiserver that we need to use instead.
if serverConfig.ControlConfig.SupervisorPort != serverConfig.ControlConfig.HTTPSPort {
serverConfig.ControlConfig.APIServerPort = cmds.AgentConfig.LBServerPort - 1
}
}
if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP.Value()) == 0 {
ip, err := util.GetIPFromInterface(cmds.AgentConfig.FlannelIface)
if err != nil {
return err
}
cmds.AgentConfig.NodeIP.Set(ip)View on GitHub (pinned to 6ba341e396)
Solutions
- For external datastores, drop --disable-etcd entirely
- For embedded-etcd joining, drop --datastore-endpoint and use --server <url> --token <token>
- Unset K3S_DATASTORE_ENDPOINT / K3S_DATASTORE_* variables if the cluster is embedded-etcd
Example fix
# before k3s server --disable-etcd --datastore-endpoint=postgres://u:p@db:5432/k3s # after k3s server --datastore-endpoint=postgres://u:p@db:5432/k3s
Defensive patterns
Strategy: validation
Validate before calling
# reject disable-etcd + datastore-endpoint combo
if printf '%s' "$@" | grep -q -- '--disable-etcd' && { printf '%s' "$@ $K3S_DATASTORE_ENDPOINT" | grep -qE '(--datastore-endpoint|K3S_DATASTORE_ENDPOINT=..)'; }; then
echo 'cannot use --disable-etcd with --datastore-endpoint'; exit 1
fi Prevention
- Pick exactly one data-plane mode per node: embedded-etcd join OR external datastore
- unset K3S_DATASTORE_ENDPOINT in units for embedded-etcd clusters
- Periodically diff rendered systemd units against the intended topology
When it happens
Trigger: `k3s server --disable-etcd --datastore-endpoint=postgres://...`, or K3S_DATASTORE_ENDPOINT exported in the unit file while config.yaml sets `disable-etcd: true`.
Common situations: Flags left over after converting cluster topology; automation templates that set both 'HA' options defensively; env-var datastore config invisible to the operator reading only config.yaml.
Related errors
- invalid flag use; --server is required with --disable-etcd
- invalid flag use; cannot use --disable-apiserver with --data
- etcd-s3-timeout must be greater than 0s
- invalid flag use; --cluster-reset required with --cluster-re
- cannot perform cluster-reset while server URL is set - remov
AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15).
Data as JSON: /api/errors/c8e17e1ac17da0c5.
Report an issue: GitHub.