FiloSottile/age · error

client failed to request confirmation

Error message

client failed to request confirmation

What it means

Confirm asks the age client to display a yes/no confirmation to the user via the confirm protocol command. This error means the client responded with a "fail" stanza — it could not present the confirmation or obtain an answer, so the plugin cannot know the user's choice.

Source

Thrown at plugin/plugin.go:567

// selected the yes or no option. Confirm returns an error if the client can't
// request the confirmation.
//
// It must only be called by a Wrap or Unwrap method invoked by [Plugin.Main].
func (p *Plugin) Confirm(prompt, yes, no string) (choseYes bool, err error) {
	args := []string{format.EncodeToString([]byte(yes))}
	if no != "" {
		args = append(args, format.EncodeToString([]byte(no)))
	}
	s := &format.Stanza{Type: "confirm", Args: args, Body: []byte(prompt)}
	if err := s.Marshal(p.stdout); err != nil {
		return false, p.fatalInteractf("failed to write confirm stanza: %v", err)
	}
	s, err = readOkOrFail(p.sr)
	if err != nil {
		return false, p.fatalInteractf("%v", err)
	}
	if s.Type == "fail" {
		return false, fmt.Errorf("client failed to request confirmation")
	}
	if err := expectStanzaWithNoBody(s, 1); err != nil {
		return false, p.fatalInteractf("%v", err)
	}
	return s.Args[0] == "yes", nil
}

// fatalInteractf prints the error to stderr and sets the broken flag, so the
// Wrap/Unwrap caller can exit with an error.
func (p *Plugin) fatalInteractf(format string, args ...any) error {
	p.broken = true
	fmt.Fprintf(p.stderr, format, args...)
	return fmt.Errorf(format, args...)
}

func (p *Plugin) fatalf(format string, args ...any) int {
	fmt.Fprintf(p.stderr, format, args...)
	return 1

View on GitHub (pinned to b74dce4cdb)

Solutions

  1. Proceed with a safe default or let the operation fail explicitly when the confirmation cannot be shown, depending on security requirements
  2. Run the workflow in an interactive environment where the client UI can confirm
  3. Upgrade the age client to one that supports the confirm command

Example fix

// before
ok, err := p.Confirm("touch device", "proceed without touch?")
if err != nil { return err }
// after
ok, err := p.Confirm("touch device", "proceed without touch?")
if err != nil {
    return fmt.Errorf("cannot confirm user intent: %w", err) // fail closed
}
Defensive patterns

Strategy: fallback

Validate before calling

// Only call Confirm when an interactive client is available:
// if !interactiveSession { use safe default instead of Confirm }

Try / catch

ok, err := p.Confirm(question, fallbackQuestion)
if err != nil {
    // fail closed or apply documented default
    return fmt.Errorf("confirmation unavailable: %w", err)
}

Prevention

When it happens

Trigger: The client has no way to show a yes/no dialog (headless run, unsupported client version); the client refuses the confirm request; the interaction channel is in a state where the client returns fail.

Common situations: Hardware-token plugins asking "touch your key / insert device" during CI or SSH sessions without an agent UI; older age clients lacking confirm support; scripting age where all UI is suppressed.

Related errors


AI-assisted analysis of FiloSottile/age@b74dce4cdb (2026-08-31). Data as JSON: /api/errors/43f6496b0d5d1e76. Report an issue: GitHub.