tailscale/tailscale · error

attestationKey.load called without tpmPrivate or tpmPublic

Error message

attestationKey.load called without tpmPrivate or tpmPublic

What it means

load was invoked on an attestationKey that is not yet loaded and has empty tpmPrivate or tpmPublic blobs, so there is nothing to hand the TPM. It means the key was deserialized from JSON or cloned without its wrapped components.

Source

Thrown at feature/tpm/attestation.go:114

		return nil
	}); err != nil {
		return nil, err
	}
	return ak, ak.load()
}

func (ak *attestationKey) loaded() bool {
	return ak.tpm != nil && ak.handle != nil && ak.pub != nil
}

// load the key into the TPM from its public/private components. Must be called
// before Sign or Public.
func (ak *attestationKey) load() error {
	if ak.loaded() {
		return nil
	}
	if len(ak.tpmPrivate.Buffer) == 0 || len(ak.tpmPublic.Bytes()) == 0 {
		return fmt.Errorf("attestationKey.load called without tpmPrivate or tpmPublic")
	}
	return withSRK(log.Printf, ak.tpm, func(srk tpm2.AuthHandle) error {
		resp, err := tpm2.Load{
			ParentHandle: tpm2.NamedHandle{
				Handle: srk.Handle,
				Name:   srk.Name,
			},
			InPrivate: ak.tpmPrivate,
			InPublic:  ak.tpmPublic,
		}.Execute(ak.tpm)
		if err != nil {
			return fmt.Errorf("tpm2.Load: %w", err)
		}

		ak.handle = &tpm2.NamedHandle{
			Handle: resp.ObjectHandle,
			Name:   resp.Name,
		}

View on GitHub (pinned to 6e0912f979)

Solutions

  1. Regenerate the attestation key with a fresh create call.
  2. Check the persisted prefs contain the key blobs.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at feature/tpm/attestation.go:114 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18). Data as JSON: /api/errors/0c6df503df552307. Report an issue: GitHub.