kubernetes/kops · error

failed to get info for Akamai (Linode) instance %q: %w

Error message

failed to get info for Akamai (Linode) instance %q: %w

What it means

After parsing the instance ID, VerifyToken calls v.client.GetInstance(ctx, instanceID) against the Linode API. If the API call returns an error (invalid/expired API token, network failure, nonexistent instance, 4xx/5xx), it is wrapped with this message including the instance ID string. This error means the verifier could not retrieve authoritative instance data from the Linode API.

Source

Thrown at upup/pkg/fi/cloudup/linode/verifier.go:77

	return &linodeVerifier{client: &client}, nil
}

// VerifyToken verifies that the given token corresponds to a valid Akamai (Linode) instance.
func (v *linodeVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request, token string, body []byte) (*bootstrap.VerifyResult, error) {
	if !strings.HasPrefix(token, linodemetadata.LinodeAuthenticationTokenPrefix) {
		return nil, bootstrap.ErrNotThisVerifier
	}

	instanceIDString := strings.TrimPrefix(token, linodemetadata.LinodeAuthenticationTokenPrefix)
	instanceID, err := strconv.Atoi(instanceIDString)
	if err != nil {
		return nil, fmt.Errorf("invalid authorization token")
	}

	instance, err := v.client.GetInstance(ctx, instanceID)
	if err != nil {
		return nil, fmt.Errorf("failed to get info for Akamai (Linode) instance %q: %w", instanceIDString, err)
	}
	if instance == nil {
		return nil, fmt.Errorf("failed to get info for Akamai (Linode) instance %q: empty response", instanceIDString)
	}

	addresses, challengeEndpoints := gatherIPv4Addresses(instance.IPv4)
	if len(challengeEndpoints) == 0 {
		return nil, fmt.Errorf("cannot determine challenge endpoint for instance id: %s", instanceIDString)
	}

	result := &bootstrap.VerifyResult{
		NodeName:          instance.Label,
		InstanceGroupName: instanceGroupNameFromTags(instance.Tags),
		CertificateNames:  addresses,
		ChallengeEndpoint: challengeEndpoints[0],
	}

	return result, nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped error: 401/403 => replace LINODE_TOKEN with a valid token with read scope for the instance's account
  2. Confirm the instance ID exists in the same Linode account as the token (linode-cli linodes list)
  3. Verify outbound HTTPS access to api.linode.com from the verifier host
  4. Retry on transient errors (5xx/429) with backoff
  5. Check linodego/API status if the failure is widespread
Defensive patterns

Strategy: retry

Validate before calling

// pre-check credentials and instance existence
if os.Getenv("LINODE_TOKEN") == "" { return errors.New("LINODE_TOKEN not set") }
cli := linodego.NewClient(nil); cli.SetToken(os.Getenv("LINODE_TOKEN"))
if _, err := cli.GetInstance(context.Background(), instanceID); err != nil { return err }

Try / catch

result, err := verifier.VerifyToken(ctx, token, certs, challenge)
if err != nil {
	var apiErr *linodego.Error
	if errors.As(err, &apiErr) && (apiErr.Code == 429 || apiErr.Code >= 500) {
		return retryWithBackoff(err)
	}
	return err
}

Prevention

When it happens

Trigger: GetInstance fails because LINODE_TOKEN is invalid/revoked/lacks scopes; the instance ID does not exist or belongs to another account; network egress from the verifier to api.linode.com is blocked; API rate limiting or outage.

Common situations: Expired or rotated LINODE_TOKEN in the verifier environment; token for a different Linode account than the one owning the instance; firewall/proxy blocking outbound 443 to api.linode.com; 429 rate-limit during bulk verification.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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