docker/cli · error
error: could not produce valid signature for
Error message
error: could not produce valid signature for %s. If Yubikey was used, was touch input provided?: %v
What it means
Returned by NotaryError for signed.ErrInsufficientSignatures (trust.go:255-256). The client attempted to produce a signature but could not create a valid one - either no eligible signing key is available in the local store/crypto service, or a hardware-backed key (Yubikey) did not yield a signature because the required user-presence/touch input was not provided. The message explicitly prompts about Yubikey touch because that is the most common hardware cause.
Solutions
- If using a Yubikey, tap it when it flashes during the push operation and ensure pcscd (or the platform smart-card service) is running; retry the push.
- Confirm the required signing key is available: run 'docker trust key list' / 'notary key list' and verify a key for the targets/releases role exists.
- Import the correct private key with 'docker trust key load <key.file>' if it is missing from the local store.
- Set DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE correctly so an encrypted software key can be decrypted for signing.
- If the role needs a delegation key, add it via 'docker trust signer add' and ensure the signer publishes with that key.
Example fix
# before: Yubikey touch missed, push fails DOCKER_CONTENT_TRUST=1 docker push myrepo/img:tag # after: tap Yubikey when it flashes, ensure daemon running sudo systemctl start pcscd DOCKER_CONTENT_TRUST=1 docker push myrepo/img:tag # tap Yubikey on prompt
Defensive patterns
Strategy: validation
Validate before calling
// Before publishing, confirm a usable signing key exists (incl. hardware-backed).
func ensureCanSign(repo client.Repository) error {
if err := ensureSigningKeyAvailable(repo, os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE")); err != nil {
return err
}
// If a Yubikey is the backing store, verify pcscd/smart-card is reachable.
if os.Getenv("DOCKER_TRUST_YUBIKEY") != "" {
if err := checkYubikeyAvailable(); err != nil {
return fmt.Errorf("Yubikey not ready for touch signing: %w", err)
}
}
return nil
} Type guard
func isErrInsufficientSignatures(err error) bool {
if err == nil {
return false
}
return errors.Is(err, signed.ErrInsufficientSignatures)
} Try / catch
if err := repo.Publish(); err != nil {
if errors.Is(err, signed.ErrInsufficientSignatures) {
return fmt.Errorf("could not produce a valid signature: %w; if using a Yubikey, tap it when it flashes", err)
}
return trust.NotaryError(gun, err)
} Prevention
- For Yubikey-backed keys, start pcscd and confirm the device is visible before the push window.
- Increase the Yubikey touch timeout or document the tap requirement for operators.
- Keep a software fallback key for CI where a hardware token is impractical.
- Pre-load the targets/releases delegation key so the signer has something to sign with.
When it happens
Trigger: During repo.Publish() or repo.AddTarget() when the signing operation needs a key that is either absent from the local key store or stored on a Yubikey that timed out waiting for touch. Also when the available signatures do not satisfy the role's signing requirements so the final signature set is insufficient to publish.
Common situations: User enabled DCT, the signing key is on a Yubikey, and during push the Yubikey LED blinked requesting touch but the user did not tap it within the timeout; Yubikey not plugged in or pcscd daemon not running; correct signing key never imported locally so no key can sign; role requires a delegation key that was removed.
Related errors
- error: could not find signing keys for remote repository
- failed to sign
- failed to generate key for
- error importing key from
- cannot load key from provided file
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/9976609aac8ad942.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/internal/trust/trust.go:256
return fmt.Errorf("error: remote repository %s out-of-date: %v", repoName, err)
case trustmanager.ErrKeyNotFound:
return fmt.Errorf("error: signing keys for remote repository %s not found: %v", repoName, err)
case storage.NetworkError:
return fmt.Errorf("error: error contacting notary server: %v", err)
case storage.ErrMetaNotFound:
return fmt.Errorf("error: trust data missing for remote repository %s or remote repository not found: %v", repoName, err)
case trustpinning.ErrRootRotationFail, trustpinning.ErrValidationFail, signed.ErrInvalidKeyType:
return fmt.Errorf("warning: potential malicious behavior - trust data mismatch for remote repository %s: %v", repoName, err)
case signed.ErrNoKeys:
return fmt.Errorf("error: could not find signing keys for remote repository %s, or could not decrypt signing key: %v", repoName, err)
case signed.ErrLowVersion:
return fmt.Errorf("warning: potential malicious behavior - trust data version is lower than expected for remote repository %s: %v", repoName, err)
case signed.ErrRoleThreshold:
return fmt.Errorf("warning: potential malicious behavior - trust data has insufficient signatures for remote repository %s: %v", repoName, err)
case client.ErrRepositoryNotExist:
return fmt.Errorf("error: remote trust data does not exist for %s: %v", repoName, err)
case signed.ErrInsufficientSignatures:
return fmt.Errorf("error: could not produce valid signature for %s. If Yubikey was used, was touch input provided?: %v", repoName, err)
default:
return err
}
}
// AddToAllSignableRoles attempts to add the image target to all the top level
// delegation roles we can (based on whether we have the signing key and whether
// the role's path allows us to).
//
// If there are no delegation roles, we add to the targets role.
func AddToAllSignableRoles(repo client.Repository, target *client.Target) error {
signableRoles, err := GetSignableRoles(repo, target)
if err != nil {
return err
}
return repo.AddTarget(target, signableRoles...)
}View on GitHub (pinned to 4f84911bfe)