kubernetes/kops · error
arn %q contains too few slashes
Error message
arn %q contains too few slashes
What it means
After confirming the ARN resource starts with "assumed-role", kOps splits it and requires at least three slash-separated segments: "assumed-role", the role name, and the session name (which kOps uses as the EC2 instance ID). This error is thrown when an assumed-role ARN lacks the session/instance-ID segment, so the instance cannot be identified.
Source
Thrown at pkg/bootstrap/awsbootstrap/verifier.go:280
return nil, fmt.Errorf("arn %q contains unexpected number of colons", arn)
}
if parts[0] != "arn" {
return nil, fmt.Errorf("arn %q doesn't start with \"arn:\"", arn)
}
if parts[1] != a.partition {
return nil, fmt.Errorf("arn %q not in partion %q", arn, a.partition)
}
if parts[2] != "iam" && parts[2] != "sts" {
return nil, fmt.Errorf("arn %q has unrecognized service", arn)
}
// parts[3] is region
// parts[4] is account
resource := strings.Split(parts[5], "/")
if resource[0] != "assumed-role" {
return nil, fmt.Errorf("arn %q has unrecognized type", arn)
}
if len(resource) < 3 {
return nil, fmt.Errorf("arn %q contains too few slashes", arn)
}
found := false
for _, role := range a.opt.NodesRoles {
if resource[1] == role {
found = true
break
}
}
if !found {
return nil, fmt.Errorf("arn %q does not contain acceptable node role", arn)
}
instanceID := resource[2]
instances, err := a.ec2.DescribeInstances(ctx, &ec2.DescribeInstancesInput{
InstanceIds: []string{instanceID},
})
if err != nil {
return nil, fmt.Errorf("describing instance for arn %q", arn)View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure nodeup obtains credentials via the instance metadata service (IMDS) so the session name is the instance ID, rather than calling AssumeRole itself.
- If assuming the node role manually for testing, set RoleSessionName to the EC2 instance ID: aws sts assume-role --role-arn ... --role-session-name i-0abc123.
- Check nodeup/kOps version consistency between control plane and nodes; upgrade outdated nodeup.
- Confirm nothing in the environment proxies or rewrites bootstrap requests with different credentials.
Example fix
// before (custom token generator)
sts.AssumeRole(&sts.AssumeRoleInput{RoleArn: r, RoleSessionName: aws.String("tmp")})
// after
sts.AssumeRole(&sts.AssumeRoleInput{RoleArn: r, RoleSessionName: aws.String(instanceID)}) Defensive patterns
Strategy: validation
Validate before calling
res := strings.Split(strings.Split(arn, ":")[5], "/")
if len(res) < 3 {
return fmt.Errorf("assumed-role ARN %q lacks session/instance-id segment; set RoleSessionName to the instance ID", arn)
} Type guard
func arnHasInstanceID(arn string) (string, bool) {
res := strings.Split(strings.Split(arn, ":")[5], "/")
if len(res) < 3 || !strings.HasPrefix(res[2], "i-") {
return "", false
}
return res[2], true
} Prevention
- Always obtain node credentials from IMDS, not from manual AssumeRole calls.
- If calling AssumeRole in tests, set --role-session-name to the EC2 instance ID.
- Keep nodeup and control-plane versions in sync.
When it happens
Trigger: verifyCallerIdentity receives an ARN like arn:aws:sts::123:assumed-role/nodes.cluster (only two resource segments, no trailing "/<session>") — i.e. an AssumeRole session was created without a meaningful RoleSessionName or the session name itself contains no instance ID.
Common situations: Custom code calling sts:AssumeRole on the node role without setting RoleSessionName to the instance ID; older kOps nodeup versions or third-party tools assuming the role with a non-instance-ID session name; hand-crafted tokens used against the challenge endpoint.
Related errors
- arn %q has unrecognized type
- getting AWS STS url: %w
- building AWS STS presigned request: %w
- arn %q does not contain acceptable node role
- parsing STS request URL: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8a96afb92967cc5c.
Report an issue: GitHub.