{"record":{"id":"60c53924f398acc6","repo":"pulumi/pulumi","slug":"host-is-required-for-grpcs-endpoint","errorCode":null,"errorMessage":"host is required for grpcs:// endpoint","messagePattern":"host is required for grpcs:// endpoint","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdk/go/common/util/otelreceiver/exporter.go","lineNumber":96,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn newFileExporter(path)\n\n\tcase \"grpc\":\n\t\thost := u.Host\n\t\tif host == \"\" {\n\t\t\treturn nil, errors.New(\"host is required for grpc:// endpoint\")\n\t\t}\n\t\treturn newGRPCExporterWithOptions(grpcExporterOptions{\n\t\t\ttarget:  host,\n\t\t\theaders: headersFromQuery(u.Query()),\n\t\t})\n\n\tcase \"grpcs\":\n\t\thost := u.Host\n\t\tif host == \"\" {\n\t\t\treturn nil, errors.New(\"host is required for grpcs:// endpoint\")\n\t\t}\n\t\treturn newGRPCExporterWithOptions(grpcExporterOptions{\n\t\t\ttarget:  host,\n\t\t\ttls:     true,\n\t\t\theaders: headersFromQuery(u.Query()),\n\t\t})\n\n\tcase \"http\", \"https\":\n\t\tif u.Host == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"host is required for %s:// endpoint\", u.Scheme)\n\t\t}\n\t\ttarget := url.URL{Scheme: u.Scheme, Host: u.Host, Path: u.Path}\n\t\tif target.Path == \"\" || target.Path == \"/\" {\n\t\t\ttarget.Path = \"/v1/traces\"\n\t\t}\n\t\treturn newHTTPExporterWithOptions(httpExporterOptions{\n\t\t\turl:     target.String(),\n\t\t\theaders: headersFromQuery(u.Query()),","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/sdk/go/common/util/otelreceiver/exporter.go#L78-L114","documentation":"This error is returned when a grpcs:// endpoint parses with an empty Host. grpcs:// selects the TLS-enabled gRPC exporter, but the exporter still requires a host:port target to dial securely. Like the grpc case, it fails fast at endpoint parsing time.","triggerScenarios":"Passing an endpoint such as \"grpcs://\" or \"grpcs://:4317\" to the OTLP exporter factory; empty authority after grpcs:// scheme.","commonSituations":"Users enabling TLS by switching grpc:// to grpcs:// but dropping the host in the edit; templated URLs where the host placeholder resolved to empty.","solutions":["Provide a host and port, e.g. grpcs://otel-collector:4317","Verify the endpoint environment variable or config value was fully interpolated","If TLS is not intended, use grpc:// with a valid host"],"exampleFix":"// before\nendpoint := \"grpcs://\"\n// after\nendpoint := \"grpcs://otel-collector:4317\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(endpoint)\nif err == nil && u.Scheme == \"grpcs\" && u.Host == \"\" {\n    return fmt.Errorf(\"endpoint %q must include a host, e.g. grpcs://collector:4317\", endpoint)\n}","typeGuard":null,"tryCatchPattern":"exp, err := newExporter(endpoint)\nif err != nil {\n    log.Fatalf(\"invalid OTLP endpoint %q: %v\", endpoint, err)\n}","preventionTips":["When toggling grpc:// to grpcs:// keep the host:port unchanged","Check that config templating fills the host placeholder","Test endpoint parsing in CI for tracing configs"],"tags":["otlp","grpc","tls","config"],"backgroundTag":"missing-endpoint-host","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}