hashicorp/terraform · error
Invalid TCP address %q for %q: %w
Error message
Invalid TCP address %q for %q: %w
What it means
ParseReattachProviders found Addr.Network="tcp" but net.ResolveTCPAddr could not parse Addr.String into host:port, so the plugin client would have no endpoint to dial. The entry is rejected and reattach aborts.
Source
Thrown at internal/getproviders/reattach/reattach.go:71
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)
}
default:
return unmanagedProviders, fmt.Errorf("Unknown address type %q for %q", c.Addr.Network, p)
}
unmanagedProviders[a] = &plugin.ReattachConfig{
Protocol: plugin.Protocol(c.Protocol),
ProtocolVersion: c.ProtocolVersion,
Pid: c.Pid,
Test: c.Test,
Addr: addr,
}
}
}
return unmanagedProviders, nil
}
// IsProviderReattached determines if a given provider is being supplied to Terraform via the TF_REATTACH_PROVIDERS
// environment variable.View on GitHub (pinned to c9def3e214)
Solutions
- Set Addr.String to a full host:port pair, e.g. "127.0.0.1:12345".
- Ensure the provider process printed its listener address before Terraform reads TF_REATTACH_PROVIDERS (serialize/launch ordering).
- For IPv6 use bracketed form like "[::1]:12345".
Example fix
// before
"Addr": {"Network":"tcp","String":"localhost"}
// after
"Addr": {"Network":"tcp","String":"127.0.0.1:12345"} Defensive patterns
Strategy: validation
Validate before calling
import "net"
// Validate a TCP reattach address before building the env var.
func validateTCPAddr(p, hostPort string) error {
if _, err := net.ResolveTCPAddr("tcp", hostPort); err != nil {
return fmt.Errorf("invalid tcp address %q for %q: %w", hostPort, p, err)
}
return nil
} Prevention
- Always include the port in Addr.String as host:port.
- Let the provider process choose a free port and emit it into the JSON.
- Bracket IPv6 literals: [::1]:port.
When it happens
Trigger: TF_REATTACH_PROVIDERS entry with Addr.Network="tcp" and an Addr.String missing a port ("127.0.0.1"), with a non-numeric port ("localhost:x"), or otherwise malformed per Go's net.ResolveTCPAddr rules.
Common situations: Dynamic port assigned by the provider process not yet substituted into the JSON template; "localhost" used where an IP is needed in a sandbox without resolver; port field accidentally serialized as a number into the string; IPv6 address written without brackets.
Related errors
- Error parsing %q as a provider address: %w
- Invalid unix socket path %q for %q: %w
- Unknown address type %q for %q
- default workspace not supported You can create a new workspa
- approved using the UI or API
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/dba0c721d229620f.
Report an issue: GitHub.