hashicorp/terraform · error

Failed to approve use of state storage provider

Error message

Failed to approve use of state storage provider: %s

What it means

In promptStateStorageProviderApproval, after a state-storage provider is installed whose trust/safety cannot be fully verified, Terraform asks the user to type 'yes' to approve it. The UIInput().Input() call itself errored (not the user typing 'no'). Wrapped %s is the input/IO error.

Solutions

  1. Pre-approve trust out-of-band so the prompt is not needed: set the provider signing/trust configuration or pin a provider version already in the lock file with known-good hashes.
  2. Run init in a real TTY when interactive approval is required, or supply `-input=false` together with a fully trusted/pinned provider.
  3. Ensure the provider's package is signed and its hashes are in .terraform.lock.hcl so approval is bypassed on subsequent inits.
  4. In embedded use, provide a UIInput that can answer the approval prompt programmatically.

Example fix

// before: CI, no TTY, new state_store provider needs interactive approval
tofu init  # -> Failed to approve use of state storage provider

// after: pre-pin trusted hashes so approval is unnecessary, run non-interactive
tofu providers lock example.com/acme/storage
tofu init -input=false
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip the interactive approval prompt when its preconditions are not met:
// no TTY, or trust already established via signed provider + lock hashes.
func shouldPromptProviderApproval(isTTY bool, lockHasSignedHashes bool) bool {
    return isTTY && !lockHasSignedHashes
}

// Pre-pin trusted hashes so approval is bypassed:
//   tofu providers lock <provider-addr>
// then commit .terraform.lock.hcl.

Try / catch

v, err := m.UIInput().Input(context.Background(), opts)
if err != nil {
    if isNoTTYErr(err) || errors.Is(err, io.EOF) {
        return diags.Append(fmt.Errorf("cannot prompt for state-store provider approval without a TTY; pre-pin trusted hashes via 'tofu providers lock %s' and re-run with -input=false: %s", lock.Provider(), err))
    }
    return diags.Append(fmt.Errorf("Failed to approve use of state storage provider: %s", err))
}

Prevention

When it happens

Trigger: m.UIInput().Input(...) errors during the state-store provider approval prompt. Triggers: non-TTY environment with input enabled, stdin closed/EOF, a UIInput implementation failure, or Ctrl-C/signal during the prompt.

Common situations: CI/container `tofu init` for a new state_store provider without a TTY; piped stdin that closes before the prompt; embedded use without a UIInput; user interrupts the approval prompt.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/cfdf400ed1a112ae. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/meta_backend.go:3235

		Id: fmt.Sprintf("approve-provider-%s-%s", lock.Provider().Type, lock.Version()), // E.g. approve-provider-aws-4.0.0. This needs to be unique in case the command needs approval for >1 provider.
		Query: fmt.Sprintf(`Do you want to use provider %q (%s), version %s, for managing state?
Platform: %s
Authentication: %s
Hashes:
%s
`,
			lock.Provider().Type,
			lock.Provider(),
			lock.Version(),
			getproviders.CurrentPlatform.String(),
			authentication,
			hashList.String(),
		),
		Description: fmt.Sprintf(`Check the details above for provider %q and confirm that you trust the provider.
	Only 'yes' will be accepted to confirm.`, lock.Provider().Type),
	})
	if err != nil {
		return diags.Append(fmt.Errorf("Failed to approve use of state storage provider: %s", err))
	}
	if v != "yes" {
		return diags.Append(
			fmt.Errorf("State store provider %q (%s) was not approved, so init cannot continue.",
				lock.Provider().Type,
				lock.Provider(),
			),
		)
	}
	return diags
}

//-------------------------------------------------------------------
// Output constants and initialization code
//-------------------------------------------------------------------

const inputCloudInitCreateWorkspace = `
There are no workspaces with the configured tags (%s)

View on GitHub (pinned to d32a084675)