{"record":{"id":"fb1d62310aad0b00","repo":"grpc/grpc-go","slug":"local-credentials-rejected-connection-to-non-local","errorCode":null,"errorMessage":"local credentials rejected connection to non-local address %q","messagePattern":"local credentials rejected connection to non-local address %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/local/local.go","lineNumber":82,"sourceCode":"\treturn c.info\n}\n\n// getSecurityLevel returns the security level for a local connection.\n// It returns an error if a connection is not local.\nfunc getSecurityLevel(network, addr string) (credentials.SecurityLevel, error) {\n\tswitch {\n\t// Local TCP connection\n\tcase strings.HasPrefix(addr, \"127.\"), strings.HasPrefix(addr, \"[::1]:\"):\n\t\treturn credentials.NoSecurity, nil\n\t// Windows named pipe connection\n\tcase network == \"pipe\" && strings.HasPrefix(addr, `\\\\.\\pipe\\`):\n\t\treturn credentials.NoSecurity, nil\n\t// UDS connection\n\tcase network == \"unix\":\n\t\treturn credentials.PrivacyAndIntegrity, nil\n\t// Not a local connection and should fail\n\tdefault:\n\t\treturn credentials.InvalidSecurityLevel, fmt.Errorf(\"local credentials rejected connection to non-local address %q\", addr)\n\t}\n}\n\nfunc (*localTC) ClientHandshake(_ context.Context, _ string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) {\n\tsecLevel, err := getSecurityLevel(conn.RemoteAddr().Network(), conn.RemoteAddr().String())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn conn, info{credentials.CommonAuthInfo{SecurityLevel: secLevel}}, nil\n}\n\nfunc (*localTC) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) {\n\tsecLevel, err := getSecurityLevel(conn.RemoteAddr().Network(), conn.RemoteAddr().String())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn conn, info{credentials.CommonAuthInfo{SecurityLevel: secLevel}}, nil\n}","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/local/local.go#L64-L100","documentation":"Thrown by getSecurityLevel in local/local.go:82 when the remote address is not recognized as a local connection (loopback 127.* or [::1]:, a Windows named pipe, or a unix-domain socket). local.NewCredentials() infers the security level purely from the connection type and refuses to run on non-local transports because it would otherwise imply a security guarantee it cannot provide.","triggerScenarios":"Calling grpc.WithTransportCredentials(local.NewCredentials()) against a remote host (e.g. 10.0.0.5:50051 or a DNS name resolving off-box), or a unix socket path that dialer resolved to a TCP address. Fires on both ClientHandshake (line 87) and ServerHandshake (line 95).","commonSituations":"Promoting a local-only prototype to a real network address without swapping local creds for TLS; a test that uses local creds but dials an in-process listener bound to 0.0.0.0; misconfigured UDS address that the resolver maps to TCP.","solutions":["Use TLS (credentials.NewClientTLSFromFile / NewTLS) for any non-loopback, non-UDS destination.","Ensure the dial target really is loopback (127.0.0.1 / localhost / [::1]) or a unix: scheme address when using local creds.","If you must keep plaintext over the wire, use insecure credentials explicitly — but only for non-sensitive traffic."],"exampleFix":"// before\nconn, _ := grpc.NewClient(\"10.0.0.5:50051\",\n    grpc.WithTransportCredentials(local.NewCredentials()),\n)\n\n// after\nconn, _ := grpc.NewClient(\"10.0.0.5:50051\",\n    grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(caPool, \"10.0.0.5\")),\n)","handlingStrategy":"validation","validationCode":"func isLocalTarget(addr string) bool {\n    h, _, _ := net.SplitHostPort(addr)\n    h = strings.ToLower(h)\n    return h == \"\" || strings.HasPrefix(addr, \"127.\") || strings.HasPrefix(addr, \"[::1]:\") ||\n        h == \"localhost\" || strings.HasPrefix(addr, \"unix:\") || strings.HasPrefix(addr, \"\\\\\\\\\\\\\\\\.\\\\pipe\\\\\\\\\")\n}\nif !isLocalTarget(addr) {\n    creds = credentials.NewClientTLSFromCert(caPool, \"\") // use TLS, not local.NewCredentials()\n}","typeGuard":null,"tryCatchPattern":"// Connection-time error from ClientHandshake/ServerHandshake:\nif strings.Contains(err.Error(), \"non-local address\") {\n    // switch dial target to loopback/UDS or switch to TLS credentials\n}","preventionTips":["Reserve local.NewCredentials() strictly for 127.0.0.1/[::1]/unix targets.","Bind dev listeners to 127.0.0.1, not 0.0.0.0, when using local creds.","Add a startup assertion that remote addresses use TLS credentials."],"tags":["local-credentials","transport","security","go","uds"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}