hashicorp/packer · error

sign payload with keyless signer: %w

Error message

sign payload with keyless signer: %w

What it means

keylessSigner.Sign signs the pre-auth-encoded payload with the ephemeral keypair's SignData; any failure from the sigstore-go keypair signer is wrapped as 'sign payload with keyless signer'. Since the key is ephemeral and in-memory, this indicates a low-level signing failure inside sigstore-go (e.g. nil context, signer state, or crypto operation error) rather than a config problem.

Source

Thrown at internal/attestation/sign_keyless.go:139

	certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
	verifier, err := newSigstoreVerifierFromPublicKey(certificate.PublicKey)
	if err != nil {
		return nil, fmt.Errorf("create keyless verifier: %w", err)
	}

	return &keylessSigner{
		keypair:  keypair,
		certPEM:  certPEM,
		cert:     certificate,
		verifier: verifier,
		keyID:    hex.EncodeToString(keypair.GetHint()),
	}, nil
}

func (s *keylessSigner) Sign(ctx context.Context, payloadType string, payload []byte) (Signature, error) {
	signature, _, err := s.keypair.SignData(ctx, PreAuthEncode(payloadType, payload))
	if err != nil {
		return Signature{}, fmt.Errorf("sign payload with keyless signer: %w", err)
	}

	return Signature{
		KeyID:   s.keyID,
		Sig:     signature,
		CertPEM: append([]byte(nil), s.certPEM...),
	}, nil
}

func (s *keylessSigner) SignBundle(ctx context.Context, payloadType string, payload []byte, cfg BackendConfig) (Envelope, []byte, error) {
	content := &sigstoregosign.DSSEData{Data: payload, PayloadType: payloadType}
	options := sigstoregosign.BundleOptions{
		CertificateProvider: staticCertificateProvider{certDER: append([]byte(nil), s.cert.Raw...)},
		Context:             ctx,
	}

	if cfg.UploadTlog {
		rekorURL := strings.TrimSpace(cfg.RekorURL)

View on GitHub (pinned to eb36e3c3e4)

Solutions

  1. Check that the ctx passed to Sign is not already canceled or past its deadline before calling
  2. Ensure the signer was constructed successfully (no earlier partial error) before calling Sign
  3. Retry the whole signing flow — the keypair is ephemeral and regenerated on each newKeylessSigner call
  4. If reproducible, check the sigstore-go version for known SignData issues and upgrade

Example fix

// before
ctx := context.Background() // possibly canceled upstream
sig, err := signer.Sign(ctx, ptype, payload)
// after
if ctx.Err() != nil { return fmt.Errorf("context canceled before signing: %w", ctx.Err()) }
sig, err := signer.Sign(ctx, ptype, payload)
Defensive patterns

Strategy: try-catch

Validate before calling

if ctx == nil || ctx.Err() != nil { return fmt.Errorf("invalid or canceled context before Sign") }

Try / catch

sig, err := signer.Sign(ctx, payloadType, payload)
if err != nil {
	if ctx.Err() != nil {
		return fmt.Errorf("signing canceled: %w", ctx.Err())
	}
	return fmt.Errorf("keyless sign failed (retry signer construction): %w", err)
}

Prevention

When it happens

Trigger: Calling Sign(ctx, payloadType, payload) on a keylessSigner created by newKeylessSigner; s.keypair.SignData(ctx, PreAuthEncode(payloadType, payload)) returns an error (internal/attestation/sign_keyless.go:137-140).

Common situations: Canceled/expired context passed to Sign; sigstore-go version bug or mismatch in SignData; nil keypair state after a partially failed signer construction in tests.

Related errors


AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05). Data as JSON: /api/errors/bc942878f9b93893. Report an issue: GitHub.