{"record":{"id":"eff6042128426402","repo":"microsoft/aspire","slug":"cannot-tunnel-endpoint-targetendpoint-endpointname-on","errorCode":null,"errorMessage":"Cannot tunnel endpoint '{targetEndpoint.EndpointName}' on resource '{targetResource.Name}' because it uses the unsupported scheme '{targetEndpoint.Scheme}'. Only 'http' and 'https' endpoints can be tunneled.","messagePattern":"Cannot tunnel endpoint '(.+?)' on resource '(.+?)' because it uses the unsupported scheme '(.+?)'\\. Only 'http' and 'https' endpoints can be tunneled\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs","lineNumber":600,"sourceCode":"            .SingleOrDefault(a => string.Equals(a.Name, targetEndpoint.EndpointName, StringComparisons.EndpointAnnotationName)) is { } targetEndpointAnnotation)\n        {\n            // The target endpoint already exists so let's ensure it's target is localhost\n            if (!EndpointHostHelpers.IsLocalhostOrLocalhostTld(targetEndpointAnnotation.TargetHost))\n            {\n                // Target endpoint is not localhost so can't be tunneled\n                throw new ArgumentException($\"Cannot tunnel endpoint '{targetEndpointAnnotation.Name}' with host '{targetEndpointAnnotation.TargetHost}' on resource '{targetResource.Name}' because it is not a localhost endpoint.\", nameof(targetEndpoint));\n            }\n        }\n\n        portOptions ??= new();\n        if (portOptions.Protocol is { } proto && proto is not \"http\" and not \"https\" and not \"auto\")\n        {\n            throw new ArgumentException($\"Invalid protocol '{proto}' specified in port options. Supported protocols are 'http', 'https', or 'auto'. Set protocol to null to use the endpoint's scheme.\", nameof(portOptions));\n        }\n        portOptions.Protocol ??= targetEndpoint.Scheme switch\n        {\n            \"https\" or \"http\" => targetEndpoint.Scheme,\n            _ => throw new ArgumentException($\"Cannot tunnel endpoint '{targetEndpoint.EndpointName}' on resource '{targetResource.Name}' because it uses the unsupported scheme '{targetEndpoint.Scheme}'. Only 'http' and 'https' endpoints can be tunneled.\"),\n        };\n        portOptions.Description ??= $\"{targetResource.Name}/{targetEndpoint.EndpointName}\";\n\n        var portName = $\"{tunnel.Name}-{targetResource.Name}-{targetEndpoint.EndpointName}\";\n        portOptions.Labels ??= [];\n        portOptions.Labels.Add(targetResource.Name);\n        portOptions.Labels.Add(targetEndpoint.EndpointName);\n\n        if (!TryValidateLabels(portOptions.Labels, out var errorMessage))\n        {\n            throw new ArgumentException(errorMessage, nameof(portOptions));\n        }\n\n        var portResource = new DevTunnelPortResource(\n            portName,\n            tunnel,\n            targetEndpoint,\n            portOptions);","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs#L582-L618","documentation":"When no explicit protocol is set in portOptions, AddDevTunnelPort infers it from the endpoint's Scheme. If the scheme is neither 'http' nor 'https' (e.g. 'tcp', 'ftp'), there is no valid tunnel protocol to map to, so an ArgumentException is thrown without a parameter name. Dev tunnels only support HTTP/HTTPS forwarding.","triggerScenarios":"Referencing an endpoint whose scheme is not http/https in WithReference(devTunnel, endpoint) without setting portOptions.Protocol — e.g. WithEndpoint(\"tcp\", e => e.Scheme = \"tcp\") then tunneling that endpoint.","commonSituations":"Tunneling database/TCP ports (Postgres, Redis) that developers assume dev tunnels support; custom endpoints declared with non-HTTP schemes.","solutions":["Tunnel only http/https endpoints; pick that endpoint on the resource.","Do not set Protocol manually for non-HTTP ports — it will not help; the transport itself is unsupported.","Use an alternative forwarding mechanism (e.g. port-forward tooling) for raw TCP services."],"exampleFix":"// before\nvar pg = builder.AddPostgres(\"pg\");\nvar tunnel = builder.AddDevTunnel(\"t\").WithReference(pg.GetEndpoint(\"tcp\")); // tcp unsupported\n// after\nvar tunnel = builder.AddDevTunnel(\"t\").WithReference(api.GetEndpoint(\"https\")); // http/https only","handlingStrategy":"validation","validationCode":"// only tunnel http/https endpoints\nif (endpoint.Scheme is not (\"http\" or \"https\"))\n    throw new InvalidOperationException($\"Endpoint {endpoint.EndpointName} scheme '{endpoint.Scheme}' cannot be tunneled\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only reference http/https endpoints in dev tunnel WithReference calls","Do not attempt to tunnel raw TCP services (databases, Redis) via dev tunnels","Declare endpoints with WithHttpEndpoint/WithHttpsEndpoint so schemes are predictable"],"tags":["devtunnels","scheme","unsupported","endpoint"],"backgroundTag":"unsupported-enum-value","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}