kubernetes/kops · error

ErrAlreadyExists

ErrAlreadyExists

Error message

node already exists

What it means

Reported when matchInstanceGroup returns an error while mapping a discovered ASG to a kops InstanceGroup in getCloudGroups. Note the ASG name is included but the underlying err is discarded, so the actual cause is hidden.

Source

Thrown at pkg/bootstrap/authenticate.go:27

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package bootstrap

import (
	"context"
	"errors"
	"net/http"

	"k8s.io/kops/pkg/nodeidentity/clusterapi"
)

var ErrAlreadyExists = errors.New("node already exists")

// Authenticator generates authentication credentials for requests.
type Authenticator interface {
	CreateToken(body []byte) (string, error)
}

// VerifyResult is the result of a successfully verified request.
type VerifyResult struct {
	// Nodename is the name that this node is authorized to use.
	NodeName string

	// InstanceGroupName is the name of the kops InstanceGroup this node is a member of.
	InstanceGroupName string

	// CAPIMachine is the Cluster API Machine object corresponding to this node, if available.
	CAPIMachine *clusterapi.Machine

	// CertificateNames is the alternate names the node is authorized to use for certificates.

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the ASG name and re-create/rename the matching kops instance group
  2. Delete the orphaned/stale ASG that carries the cluster tags but no matching instance group
  3. Ensure ASG names follow the kops convention <instancegroup>.<clustername>
  4. Replace the `err` in the message with `%v` wrap to expose the real cause before debugging

Example fix

// before
return nil, fmt.Errorf("error getting instance group for ASG %q", name)
// after
return nil, fmt.Errorf("error getting instance group for ASG %q: %v", name, err)
Defensive patterns

Strategy: validation

Validate before calling

for _, asg := range asgs {
  if _, err := matchInstanceGroup(aws.ToString(asg.AutoScalingGroupName), cluster.Name, igs); err != nil {
    klog.Warningf("skipping unmatchable ASG %q", aws.ToString(asg.AutoScalingGroupName))
  }
}

Type guard

func matchesClusterASG(name, clusterName string, igs []*kops.InstanceGroup) bool {
  return matchInstanceGroup(name, clusterName, igs) == nil
}

Try / catch

groups, err := cloud.GetCloudGroups(ctx, cluster, igs, true, nodes)
if err != nil && strings.Contains(err.Error(), "error getting instance group for ASG") {
  // extract ASG name from %q and delete or rename the orphaned ASG
  name := extractQuoted(err)
  cleanupOrphanedASG(name)
}

Prevention

When it happens

Trigger: matchInstanceGroup errors when the ASG name's machine-type suffix cannot be parsed against the cluster's instance groups — e.g. ASG naming like `nodes.foo-1234` does not correspond to any kops instance group role/spec pattern.

Common situations: ASG was renamed or created manually with kops cluster tags but a non-standard name; stale ASGs left from a previous cluster with the same name; instance group renamed in the kops spec while old ASGs still exist.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/9a7eb5b8c445da4f. Report an issue: GitHub.