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
- Check that the ctx passed to Sign is not already canceled or past its deadline before calling
- Ensure the signer was constructed successfully (no earlier partial error) before calling Sign
- Retry the whole signing flow — the keypair is ephemeral and regenerated on each newKeylessSigner call
- 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
- Always pass a live, non-canceled context to Sign
- Treat Sign failures as retryable by reconstructing the signer (fresh ephemeral keypair)
- Keep sigstore-go up to date
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
- signing_mode %q does not support Sigstore bundle emission
- create keyless verifier: %w
- static certificate provider is missing a certificate
- read signer %q: %w
- decode signer %q: no PEM block found
AI-assisted analysis of hashicorp/packer@eb36e3c3e4 (2026-09-05).
Data as JSON: /api/errors/bc942878f9b93893.
Report an issue: GitHub.