GoogleContainerTools/skaffold · error

failed to unmarshal gcloud command result into access token

Error message

failed to unmarshal gcloud command result into access token %v

What it means

Fires in tokenSource.Token when the JSON emitted by `gcloud auth print-access-token --format=json` cannot be unmarshalled into the expected {token: ...} structure — gcloud produced unexpected output (version mismatch, error text on stdout, or login prompt).

Source

Thrown at pkg/skaffold/gcp/auth.go:82

type token struct {
	Token string `json:"token"`
}

type tokenSource struct {
}

func (ts tokenSource) Token() (*oauth2.Token, error) {
	// the command return a json object containing token
	cmd := exec.Command("gcloud", "auth", "print-access-token", "--format=json")
	var body bytes.Buffer
	cmd.Stdout = &body
	err := util.RunCmd(context.TODO(), cmd)
	if err != nil {
		return nil, fmt.Errorf("failed to get access token %v", err)
	}
	var t token
	if err := json.Unmarshal(body.Bytes(), &t); err != nil {
		return nil, fmt.Errorf("failed to unmarshal gcloud command result into access token %v", err)
	}
	return &oauth2.Token{AccessToken: t.Token}, nil
}

func activeUserCredentialsOnce() (*google.Credentials, error) {
	credsOnce.Do(func() {
		c, err := activeUserCredentials()
		if err != nil {
			log.Entry(context.TODO()).Infof("unable to retrieve gcloud access token: %v", err)
			log.Entry(context.TODO()).Info("falling back to application default credentials")
			credsErr = fmt.Errorf("retrieving gcloud access token: %w", err)
			return
		}
		creds = c
	})

	return creds, credsErr
}

View on GitHub (pinned to a1189de023)

Solutions

  1. Update gcloud: `gcloud components update`, then re-run.
  2. Run the command manually (`gcloud auth print-access-token --format=json`) and confirm valid JSON on stdout.
  3. Complete any pending gcloud consent/login prompts interactively once so non-TTY runs no longer prompt.
  4. Bypass gcloud user auth by using GOOGLE_APPLICATION_CREDENTIALS / ADC instead.

Example fix

// before: output = "Your browser has been opened..." (prompt)
// after
$ gcloud auth login   # complete once interactively
$ gcloud components update
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm the command emits JSON
out, err := exec.Command("gcloud", "auth", "print-access-token", "--format=json").Output()
if err == nil && !json.Valid(out) {
    return fmt.Errorf("gcloud output is not JSON; update gcloud SDK")
}

Try / catch

tok, err := tokenSource.Token()
if err != nil && strings.Contains(err.Error(), "failed to unmarshal gcloud command result") {
    return fmt.Errorf("update gcloud (`gcloud components update`) and clear interactive prompts: %w", err)
}

Prevention

When it happens

Trigger: Calling Token when gcloud succeeds (exit 0) but prints non-JSON output — e.g. an old gcloud version lacking --format=json support for this command, warnings/interactive prompts mixed into stdout, or a wrapper script altering output.

Common situations: Outdated Google Cloud SDK where `gcloud auth print-access-token --format=json` prints plain text; gcloud prompting for consent on first run in a non-TTY; shell wrappers/aliases injecting banners; locale/encoding issues corrupting output.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/2f8cae5fb32545cf. Report an issue: GitHub.