{"record":{"id":"dba0c721d229620f","repo":"hashicorp/terraform","slug":"invalid-tcp-address-q-for-q-w","errorCode":null,"errorMessage":"Invalid TCP address %q for %q: %w","messagePattern":"Invalid TCP address %q for %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getproviders/reattach/reattach.go","lineNumber":71,"sourceCode":"\t\tif err != nil {\n\t\t\treturn unmanagedProviders, fmt.Errorf(\"Invalid format for %s: %w\", TF_REATTACH_PROVIDERS, err)\n\t\t}\n\t\tfor p, c := range m {\n\t\t\ta, diags := addrs.ParseProviderSourceString(p)\n\t\t\tif diags.HasErrors() {\n\t\t\t\treturn unmanagedProviders, fmt.Errorf(\"Error parsing %q as a provider address: %w\", a, diags.Err())\n\t\t\t}\n\t\t\tvar addr net.Addr\n\t\t\tswitch c.Addr.Network {\n\t\t\tcase \"unix\":\n\t\t\t\taddr, err = net.ResolveUnixAddr(\"unix\", c.Addr.String)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn unmanagedProviders, fmt.Errorf(\"Invalid unix socket path %q for %q: %w\", c.Addr.String, p, err)\n\t\t\t\t}\n\t\t\tcase \"tcp\":\n\t\t\t\taddr, err = net.ResolveTCPAddr(\"tcp\", c.Addr.String)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn unmanagedProviders, fmt.Errorf(\"Invalid TCP address %q for %q: %w\", c.Addr.String, p, err)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn unmanagedProviders, fmt.Errorf(\"Unknown address type %q for %q\", c.Addr.Network, p)\n\t\t\t}\n\t\t\tunmanagedProviders[a] = &plugin.ReattachConfig{\n\t\t\t\tProtocol:        plugin.Protocol(c.Protocol),\n\t\t\t\tProtocolVersion: c.ProtocolVersion,\n\t\t\t\tPid:             c.Pid,\n\t\t\t\tTest:            c.Test,\n\t\t\t\tAddr:            addr,\n\t\t\t}\n\t\t}\n\t}\n\treturn unmanagedProviders, nil\n}\n\n// IsProviderReattached determines if a given provider is being supplied to Terraform via the TF_REATTACH_PROVIDERS\n// environment variable.","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getproviders/reattach/reattach.go#L53-L89","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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\"."],"exampleFix":"// before\n\"Addr\": {\"Network\":\"tcp\",\"String\":\"localhost\"}\n// after\n\"Addr\": {\"Network\":\"tcp\",\"String\":\"127.0.0.1:12345\"}","handlingStrategy":"validation","validationCode":"import \"net\"\n\n// Validate a TCP reattach address before building the env var.\nfunc validateTCPAddr(p, hostPort string) error {\n    if _, err := net.ResolveTCPAddr(\"tcp\", hostPort); err != nil {\n        return fmt.Errorf(\"invalid tcp address %q for %q: %w\", hostPort, p, err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["terraform","reattach","tcp","tf-reattach-providers"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}