kubernetes/kops · critical
DIGITALOCEAN_ACCESS_TOKEN is required
Error message
DIGITALOCEAN_ACCESS_TOKEN is required
What it means
The DigitalOcean bootstrap verifier authenticates incoming kubelet requests against the DO API. NewVerifier reads DIGITALOCEAN_ACCESS_TOKEN from the environment and returns this identical error when it is unset/empty, before any API call is made.
Source
Thrown at upup/pkg/fi/cloudup/do/verifier.go:48
"golang.org/x/oauth2"
"k8s.io/kops/pkg/bootstrap"
"k8s.io/kops/pkg/wellknownports"
"k8s.io/kops/upup/pkg/fi/cloudup/do/dometadata"
)
type DigitalOceanVerifierOptions struct {
}
type digitalOceanVerifier struct {
doClient *godo.Client
}
var _ bootstrap.Verifier = (*digitalOceanVerifier)(nil)
func NewVerifier(ctx context.Context, opt *DigitalOceanVerifierOptions) (bootstrap.Verifier, error) {
accessToken := os.Getenv("DIGITALOCEAN_ACCESS_TOKEN")
if accessToken == "" {
return nil, errors.New("DIGITALOCEAN_ACCESS_TOKEN is required")
}
tokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: accessToken})
doClient := godo.NewClient(oauth2.NewClient(ctx, tokenSource))
return &digitalOceanVerifier{
doClient: doClient,
}, nil
}
func (o digitalOceanVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request, token string, body []byte) (*bootstrap.VerifyResult, error) {
if !strings.HasPrefix(token, dometadata.DOAuthenticationTokenPrefix) {
return nil, bootstrap.ErrNotThisVerifier
}
serverIDString := strings.TrimPrefix(token, dometadata.DOAuthenticationTokenPrefix)
serverID, err := strconv.Atoi(serverIDString)
if err != nil {View on GitHub (pinned to 4c8573c808)
Solutions
- Export DIGITALOCEAN_ACCESS_TOKEN in the environment where the verifier runs
- Ensure the node bootstrap/manifest passes the token env var into the verifier process
- Verify with printenv DIGITALOCEAN_ACCESS_TOKEN that it is non-empty in the target runtime (container/systemd unit)
- Use a DO token scoped to read droplets metadata for the verifier
Example fix
// systemd unit before ExecStart=/usr/local/bin/do-verifier // after Environment=DIGITALOCEAN_ACCESS_TOKEN=dop_v1_xxxx ExecStart=/usr/local/bin/do-verifier
Defensive patterns
Strategy: validation
Validate before calling
if os.Getenv("DIGITALOCEAN_ACCESS_TOKEN") == "" {
return errors.New("verifier requires DIGITALOCEAN_ACCESS_TOKEN in its runtime environment")
} Try / catch
v, err := do.NewVerifier(ctx, opts)
if err != nil {
if err.Error() == "DIGITALOCEAN_ACCESS_TOKEN is required" {
// inject env var into the verifier's runtime (systemd/container)
} else { return err }
} Prevention
- Ensure node bootstrap images/units propagate the token env to the verifier
- For containers, pass -e DIGITALOCEAN_ACCESS_TOKEN at runtime
- Smoke-test the verifier binary with printenv before production bootstrap
When it happens
Trigger: Running a kops-built DigitalOcean verifier binary (used by nodeup/bootstrap on new nodes) in an environment without DIGITALOCEAN_ACCESS_TOKEN set — the main() entry point calls NewVerifier which fails immediately.
Common situations: Bootstrapping new DO nodes where the verifier was run manually without env; container images missing the env var; secrets not mounted into the verifier's runtime environment.
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
- DIGITALOCEAN_ACCESS_TOKEN is required
- failed to initialize digitalocean cloud: %s
- failed to list vpcs: %v
- %s is required
- required S3_ENDPOINT env var for path: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/805bdaea6bb0c751.
Report an issue: GitHub.