kubernetes/kops · error
invalid authorization token
Error message
invalid authorization token
What it means
VerifyToken authenticates node bootstrap requests. The presented token must have the linodemetadata.LinodeAuthenticationTokenPrefix; the suffix is expected to be the numeric Linode instance ID. If the suffix does not parse as an integer via strconv.Atoi, the token is rejected with 'invalid authorization token'. It is a static message — the underlying parse error is deliberately not included.
Source
Thrown at upup/pkg/fi/cloudup/linode/verifier.go:72
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")
}
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),View on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the client sends prefix + numeric instance ID exactly as defined in linodemetadata.LinodeAuthenticationTokenPrefix
- Check client/server kOps versions match so the token format is identical
- Log the received token shape (prefix only, never the secret) to see what the suffix actually contains
- If you control the caller, strconv-quote or sanitize the ID before composing the token
Example fix
// before (caller) token := linodemetadata.LinodeAuthenticationTokenPrefix + instanceLabel // after (caller) token := linodemetadata.LinodeAuthenticationTokenPrefix + strconv.Itoa(instanceID)
Defensive patterns
Strategy: validation
Validate before calling
idStr := strings.TrimPrefix(token, linodemetadata.LinodeAuthenticationTokenPrefix)
if _, err := strconv.Atoi(idStr); err != nil {
return errors.New("token must be " + linodemetadata.LinodeAuthenticationTokenPrefix + "<numeric-instance-id>")
} Type guard
func isValidLinodeAuthToken(token string) bool {
idStr := strings.TrimPrefix(token, linodemetadata.LinodeAuthenticationTokenPrefix)
_, err := strconv.Atoi(idStr)
return err == nil
} Try / catch
result, err := verifier.VerifyToken(ctx, token, certificates, challenge)
if err != nil {
if strings.Contains(err.Error(), "invalid authorization token") {
return errors.New("client sent malformed token; expected prefix + numeric instance id")
}
return err
} Prevention
- Mint tokens only via the shared linodemetadata helpers so prefix+ID format stays consistent
- Keep client and verifier kOps versions aligned
- Never send raw API tokens where the composite bootstrap token is expected
- Sanitize/trim the instance ID before composing the token
When it happens
Trigger: A client presents a token with the correct prefix but a non-numeric remainder (e.g. 'linode:abc123'), or an empty remainder (bare prefix), so strconv.Atoi fails. Called from bootstrap verification flow; exercised by TestLinodeVerifierVerifyToken* tests.
Common situations: Node agent configured with a raw API token instead of the expected 'prefix+instanceID' composite token; version mismatch between the client that mints tokens and the verifier's expected format; manual curl testing against the verifier endpoint with a made-up token; whitespace or URL-encoding corrupting the ID.
Related errors
- node identity is required
- getting AWS credentials: %w
- unable to verify token
- unmarshalling authorization token data: %w
- incorrect Audience
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d921c7ac88ca2220.
Report an issue: GitHub.