hashicorp/terraform · error

Invalid format for

Error message

Invalid format for %s: %w

What it means

Thrown by the reattach config loader when the TF_REATTACH_PROVIDERS environment variable cannot be unmarshalled into a map[string]reattachConfig. The value must be valid JSON keyed by provider source string.

Solutions

  1. Validate the TF_REATTACH_PROVIDERS JSON with a linter before exporting it
  2. Re-emit the value from the test helper / debug command that produced it
  3. Ensure shell quoting preserves the literal JSON (single-quote the whole value in sh)

Example fix

# before
export TF_REATTACH_PROVIDERS='{"registry.terraform.io/hashicorp/null": {"protocol":"grpc","protocol_version":5,"addr":{"network":"unix","string":"/tmp/null"}}}'

# ensure balanced braces and double quotes; re-export and retry
Defensive patterns

Strategy: validation

Validate before calling

// Validate the env var parses as JSON before passing it to the loader.
var probe map[string]json.RawMessage
if err := json.Unmarshal([]byte(raw), &probe); err != nil {
    return fmt.Errorf("TF_REATTACH_PROVIDERS is not valid JSON: %w", err)
}

Type guard

func IsReattachJSON(s string) bool {
    var m map[string]json.RawMessage
    return json.Unmarshal([]byte(s), &m) == nil
}

Try / catch

providers, err := reattach.DecodeProviders(raw)
if err != nil {
    return fmt.Errorf("invalid TF_REATTACH_PROVIDERS: %w", err)
}

Prevention

When it happens

Trigger: json.Unmarshal([]byte(in), &m) returned a non-nil error while parsing the TF_REATTACH_PROVIDERS value.

Common situations: TF_REATTACH_PROVIDERS set to malformed JSON (trailing comma, single quotes, unquoted keys); value copy-pasted from a log with truncation; shell quoting that broke the JSON; missing closing brace.

Related errors


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

Appendix: source

Thrown at internal/getproviders/reattach/reattach.go:54

//
// Calling code is expected to pass in the value of os.Getenv("TF_REATTACH_PROVIDERS")
func ParseReattachProviders(in string) (map[addrs.Provider]*plugin.ReattachConfig, error) {
	unmanagedProviders := map[addrs.Provider]*plugin.ReattachConfig{}
	if in != "" {
		type reattachConfig struct {
			Protocol        string
			ProtocolVersion int
			Addr            struct {
				Network string
				String  string
			}
			Pid  int
			Test bool
		}
		var m map[string]reattachConfig
		err := json.Unmarshal([]byte(in), &m)
		if err != nil {
			return unmanagedProviders, fmt.Errorf("Invalid format for %s: %w", TF_REATTACH_PROVIDERS, err)
		}
		for p, c := range m {
			a, diags := addrs.ParseProviderSourceString(p)
			if diags.HasErrors() {
				return unmanagedProviders, fmt.Errorf("Error parsing %q as a provider address: %w", a, diags.Err())
			}
			var addr net.Addr
			switch c.Addr.Network {
			case "unix":
				addr, err = net.ResolveUnixAddr("unix", c.Addr.String)
				if err != nil {
					return unmanagedProviders, fmt.Errorf("Invalid unix socket path %q for %q: %w", c.Addr.String, p, err)
				}
			case "tcp":
				addr, err = net.ResolveTCPAddr("tcp", c.Addr.String)
				if err != nil {
					return unmanagedProviders, fmt.Errorf("Invalid TCP address %q for %q: %w", c.Addr.String, p, err)
				}

View on GitHub (pinned to d32a084675)