kubernetes/kops · error

failed to marshal token: %w

Error message

failed to marshal token: %w

What it means

After signing, CreateToken marshals the gcetpm.AuthToken {Data, Signature} struct to JSON before base64-encoding it into the final prefixed token string. This wraps a json.Marshal failure of the AuthToken. Like the payload marshal, it should never fire for these byte-slice fields and signals a code-level problem.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner/tpmauthenticator.go:112

	}

	payload, err := json.Marshal(&data)
	if err != nil {
		return "", fmt.Errorf("failed to marshal token data: %w", err)
	}

	signature, err := tpmSign(key, payload)
	if err != nil {
		return "", fmt.Errorf("failed to sign token data: %w", err)
	}
	token := &gcetpm.AuthToken{
		Data:      payload,
		Signature: signature,
	}

	b, err := json.Marshal(token)
	if err != nil {
		return "", fmt.Errorf("failed to marshal token: %w", err)
	}
	return gcetpm.GCETPMAuthenticationTokenPrefix + base64.StdEncoding.EncodeToString(b), nil
}

// tpmSign performs a TPM signature with the tpmKey, and sanity checks the result.
func tpmSign(tpmKey *client.Key, payload []byte) ([]byte, error) {
	beforeSign := time.Now()
	signature, err := tpmKey.SignData(payload)
	if err != nil {
		return nil, fmt.Errorf("failed to sign data with TPM: %w", err)
	}

	klog.Infof("TPM signing took %v", time.Since(beforeSign))

	return signature, nil
}

func debugToPEM(key crypto.PublicKey) string {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped error for the failing field
  2. Fix/remove custom MarshalJSON on gcetpm.AuthToken
  3. Keep Data and Signature as []byte (correct base64-encodable JSON types)
  4. Ensure both node (signer) and server (verifier) use the same gcetpm package version

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := json.Marshal(gcetpm.AuthToken{}); err != nil {
    // schema regression detected in tests
    panic(err)
}

Try / catch

token, err := authenticator.CreateToken(ctx, request)
if err != nil && strings.Contains(err.Error(), "failed to marshal token") {
    return fmt.Errorf("token schema regression: %w", err)
}

Prevention

When it happens

Trigger: json.Marshal(token) returns an error — only via a faulty custom MarshalJSON on AuthToken or an unsupported field type introduced in the struct.

Common situations: Refactors that add non-serializable fields or a broken MarshalJSON to gcetpm.AuthToken; version skew between vendored gcetpm package copies.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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