kubernetes/kops · critical
%s is required
Error message
%s is required
What it means
NewLinodeVerifier builds a bootstrap.Verifier for Akamai (Linode) instance tokens and requires a Linode API access token. It reads LINODE_TOKEN from the environment; if the variable is unset or empty, construction fails immediately with '%s is required' where the placeholder is filled with LINODE_TOKEN. No Linode client can be created without credentials, so this is an intentional fail-fast guard.
Source
Thrown at upup/pkg/fi/cloudup/linode/verifier.go:50
)
type LinodeVerifierOptions struct{}
type linodeVerifierClient interface {
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
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Export LINODE_TOKEN with a valid Linode API access token in the environment of the process running the verifier
- If running under systemd or a container, add the env var to the unit file / container spec rather than the interactive shell
- Check the exact variable name is LINODE_TOKEN (no typos or alternate names)
- Verify with: echo "${LINODE_TOKEN:?not set}" before launching
- In tests, set t.Setenv("LINODE_TOKEN", "dummy") before calling NewLinodeVerifier
Example fix
// before (shell) kops executor verify --v=2 // after (shell) export LINODE_TOKEN="<linode-api-access-token>" kops executor verify --v=2
Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("LINODE_TOKEN") == "" {
return errors.New("LINODE_TOKEN is required")
} Try / catch
verifier, err := linode.NewLinodeVerifier(opts)
if err != nil {
if strings.Contains(err.Error(), "LINODE_TOKEN is required") {
return fmt.Errorf("set LINODE_TOKEN in the service environment: %w", err)
}
return err
} Prevention
- Fail fast at process startup if LINODE_TOKEN is unset: ${LINODE_TOKEN:?not set}
- Configure the var in systemd units / container specs, not just interactive shells
- Use the exact name LINODE_TOKEN
- For tests use t.Setenv("LINODE_TOKEN", "test-token")
When it happens
Trigger: NewLinodeVerifier(opt) is called while os.Getenv("LINODE_TOKEN") returns "" — the variable is not exported in the verifier's environment, is set to an empty string, or is defined only in a shell profile not loaded by the kOps process (e.g. systemd service, container).
Common situations: Running the verifier/bastion on a node where credentials were never provisioned; exporting LINODE_TOKEN in an interactive shell but launching kops via systemd/k8s which has a different env; CI jobs missing the secret in their env config; typo such as LINODE_API_TOKEN instead of LINODE_TOKEN.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- error listing Akamai (Linode) instances: %w
- invalid authorization token
- failed to get info for Akamai (Linode) instance %q: %w
- Subnet.ID is required
- Count must be positive or 0
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/be31152e5ef72879.
Report an issue: GitHub.