{"record":{"id":"ee808d6d977160a1","repo":"microsoft/aspire","slug":"external-non-http-s-endpoints-are-not-supported","errorCode":null,"errorMessage":"External non-HTTP(s) endpoints are not supported","messagePattern":"External non-HTTP\\(s\\) endpoints are not supported","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Azure.AppContainers/ContainerAppContext.cs","lineNumber":179,"sourceCode":"                IsHttpOnly = g.All(x => x.resolved.Endpoint.Transport is \"http\" or \"http2\"),\n                AnyH2 = g.Any(x => x.resolved.Endpoint.Transport is \"http2\"),\n                UniqueTransports = g.Select(x => x.resolved.Endpoint.Transport).Distinct().ToArray(),\n                Index = g.Min(x => x.index)\n            })\n            .ToList();\n\n        // Failure cases\n\n        // Multiple external endpoints are not supported\n        if (endpointsByTargetPort.Count(g => g.External) > 1)\n        {\n            throw new NotSupportedException(\"Multiple external endpoints are not supported\");\n        }\n\n        // Any external non-http endpoints are not supported\n        if (endpointsByTargetPort.Any(g => g.External && !g.IsHttpOnly))\n        {\n            throw new NotSupportedException(\"External non-HTTP(s) endpoints are not supported\");\n        }\n\n        // Don't allow mixing http and tcp transports on the same target port\n        static bool Compatible(string[] transports) =>\n            transports.All(t => t is \"http\" or \"http2\") || transports.All(t => t is \"tcp\");\n\n        if (endpointsByTargetPort.Any(g => !Compatible(g.UniqueTransports)))\n        {\n            throw new NotSupportedException(\"HTTP(s) and TCP endpoints cannot be mixed\");\n        }\n\n        // Get all http only groups\n        var httpOnlyEndpoints = endpointsByTargetPort.Where(g => g.IsHttpOnly).OrderBy(g => g.Index).ToArray();\n\n        // Do we only have one?\n        var httpIngress = httpOnlyEndpoints.Length == 1 ? httpOnlyEndpoints[0] : null;\n\n        if (httpIngress is null)","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Azure.AppContainers/ContainerAppContext.cs#L161-L197","documentation":"Container Apps external ingress only supports HTTP(S) traffic. Aspire validates that any endpoint group marked external consists of http/http2 endpoints only; an external tcp endpoint triggers this NotSupportedException. Expose the tcp endpoint internally instead.","triggerScenarios":"Publishing a resource to Container Apps with an endpoint marked isExternal: true whose transport is tcp (e.g., a public database or game-server port).","commonSituations":"Attempting to publicly expose raw TCP services (Redis, databases, custom protocols) through Container Apps ingress; lifting an app model from a platform that allows external TCP (e.g., LoadBalancer Services) onto Container Apps.","solutions":["Set the tcp endpoint to internal (isExternal: false) and access it via service discovery inside the environment.","Remove external exposure and put a suitable public gateway/proxy (HTTP) in front if public TCP is truly required.","Move that workload off Container Apps if public TCP ingress is a hard requirement."],"exampleFix":"// before\n.WithEndpoint(6379, e => e.Name = \"redis\", isExternal: true).WithTransport(\"tcp\");\n\n// after\n.WithEndpoint(6379, e => e.Name = \"redis\", isExternal: false).WithTransport(\"tcp\");","handlingStrategy":"validation","validationCode":"var badExternal = resource.GetEndpoints().Where(e => e.Endpoint.IsExternal && e.Endpoint.Transport == \"tcp\");\nif (badExternal.Any()) throw new InvalidOperationException(\"External tcp endpoints are not supported on Container Apps.\");","typeGuard":"bool IsHttpExternal(EndpointAnnotation a) => !a.IsExternal || a.Transport is \"http\" or \"http2\";","tryCatchPattern":"try { /* build/publish */ } catch (NotSupportedException ex) when (ex.Message.Contains(\"External non-HTTP\")) { /* make tcp endpoint internal */ }","preventionTips":["Never mark tcp endpoints external when targeting Container Apps.","Consume internal TCP services via service discovery within the environment.","If public TCP is required, choose a hosting product that supports it."],"tags":["azure","container-apps","endpoints","tcp","ingress"],"backgroundTag":"invalid-argument-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"}