kubernetes/kops · error

failed to create Linode client: %w

Error message

failed to create Linode client: %w

What it means

After validating the token, NewLinodeVerifier constructs an API client via linodego.NewClient(nil). If the underlying linodego library cannot initialize its client (rare; typically an internal init failure in the SDK), the error is wrapped with this message. This is distinct from authentication failures — it happens before any HTTP call is made.

Source

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

	GetInstance(ctx context.Context, linodeID int) (*linodego.Instance, error)
}

type linodeVerifier struct {
	client linodeVerifierClient
}

var _ bootstrap.Verifier = (*linodeVerifier)(nil)

// NewLinodeVerifier returns a bootstrap.Verifier that can verify Akamai (Linode) instance tokens using the LINODE_TOKEN environment variable.
func NewLinodeVerifier(opt *LinodeVerifierOptions) (bootstrap.Verifier, error) {
	accessToken := os.Getenv("LINODE_TOKEN")
	if accessToken == "" {
		return nil, fmt.Errorf("%s is required", "LINODE_TOKEN")
	}

	client, err := linodego.NewClient(nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create Linode client: %w", err)
	}
	client.SetUserAgent("kops")
	client.SetToken(accessToken)

	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")
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped (%w) cause from linodego for the actual initialization failure
  2. Update or align the linodego dependency version (go get go.linode.com/linodego@latest && make gomod)
  3. Construct the client manually (linodego.NewClient(&http.Client{...})) to bypass the failing default and isolate the cause
  4. Pin a known-good linodego version if the regression appeared after a dependency bump

Example fix

// before
client, err := linodego.NewClient(nil)
if err != nil {
	return nil, fmt.Errorf("failed to create Linode client: %w", err)
}
// after
httpClient := &http.Client{Timeout: 30 * time.Second}
client, err := linodego.NewClient(httpClient)
if err != nil {
	return nil, fmt.Errorf("failed to create Linode client: %w", err)
}
Defensive patterns

Strategy: try-catch

Try / catch

client, err := linodego.NewClient(nil)
if err != nil {
	return fmt.Errorf("failed to create Linode client: %w", err)
}

Prevention

When it happens

Trigger: linodego.NewClient(nil) returns a non-nil err. This occurs only when the linodego SDK's internal client construction fails (SDK-internal issue, e.g. broken default HTTP client setup), not from bad tokens.

Common situations: Pinned/old or vendored linodego version with a client-construction regression; exotic environments where the SDK's default transport setup fails; seen almost exclusively during SDK upgrades or dependency mismatches.

Related errors


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