{"record":{"id":"88fb30478a6f6b96","repo":"AlexxIT/go2rtc","slug":"pinggy-unsupported-proto-proto","errorCode":null,"errorMessage":"pinggy: unsupported proto: ${proto}","messagePattern":"pinggy: unsupported proto: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/pinggy/pinggy.go","lineNumber":27,"sourceCode":"\t\"net/http\"\n\t\"time\"\n\n\t\"golang.org/x/crypto/ssh\"\n)\n\ntype Client struct {\n\tSSH *ssh.Client\n\tTCP net.Listener\n\tAPI *http.Client\n}\n\nfunc NewClient(proto string) (*Client, error) {\n\tswitch proto {\n\tcase \"http\", \"tcp\", \"tls\", \"tlstcp\":\n\tcase \"\":\n\t\tproto = \"http\"\n\tdefault:\n\t\treturn nil, errors.New(\"pinggy: unsupported proto: \" + proto)\n\t}\n\n\tconfig := &ssh.ClientConfig{\n\t\tUser:            \"auth+\" + proto,\n\t\tAuth:            []ssh.AuthMethod{ssh.Password(\"nopass\")},\n\t\tHostKeyCallback: ssh.InsecureIgnoreHostKey(),\n\t\tTimeout:         5 * time.Second,\n\t}\n\n\tclient, err := ssh.Dial(\"tcp\", \"a.pinggy.io:443\", config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tln, err := client.Listen(\"tcp\", \"0.0.0.0:0\")\n\tif err != nil {\n\t\t_ = client.Close()\n\t\treturn nil, err","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/pinggy/pinggy.go#L9-L45","documentation":"NewClient validates the tunnel protocol string before creating the SSH-based pinggy client. Only \"http\", \"tcp\", \"tls\" and \"tlstcp\" are accepted; an empty string defaults to \"http\". Anything else throws this error.","triggerScenarios":"Calling NewClient (via proxy) with proto values like \"https\", \"ssh\", \"UDP\", or any string not in the allowed set.","commonSituations":"Passing \"https\" thinking TLS tunnel means https; case mistakes like \"HTTP\"; copying proto names from other tunnel tools.","solutions":["Use one of: \"http\", \"tcp\", \"tls\", \"tlstcp\"","Pass \"\" to default to \"http\"","Normalize/validate user input case before calling NewClient"],"exampleFix":"// before\nc, err := pinggy.NewClient(\"https\")\n// after\nc, err := pinggy.NewClient(\"tls\")","handlingStrategy":"validation","validationCode":"var validProtos = map[string]bool{\"http\": true, \"tcp\": true, \"tls\": true, \"tlstcp\": true, \"\": true}\nif !validProtos[proto] {\n    return fmt.Errorf(\"proto must be http|tcp|tls|tlstcp, got %q\", proto)\n}","typeGuard":null,"tryCatchPattern":"c, err := pinggy.NewClient(proto)\nif err != nil && strings.Contains(err.Error(), \"unsupported proto\") {\n    c, err = pinggy.NewClient(\"\") // default to http\n}","preventionTips":["Keep the allowed proto list next to the call site as a const set","Lowercase/trim user-supplied proto values before calling","Don't assume https is valid — use \"tls\" or \"tlstcp\""],"tags":["tunnel","proxy","invalid-enum-value"],"backgroundTag":"invalid-enum-value","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}