{"record":{"id":"f804931246973f30","repo":"cloudflare/cloudflared","slug":"either-servername-or-insecureskipverify-must-be-sp","errorCode":null,"errorMessage":"either ServerName or InsecureSkipVerify must be specified in the tls.Config","messagePattern":"either ServerName or InsecureSkipVerify must be specified in the tls\\.Config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tlsconfig/origin_ca.go","lineNumber":107,"sourceCode":"\t}\n\n\tif tlsConfig.RootCAs == nil {\n\t\trootCAPool, err := x509.SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"unable to get x509 system cert pool\")\n\t\t}\n\t\tcfRootCA, err := GetCloudflareRootCA()\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"could not append Cloudflare Root CAs to cloudflared certificate pool\")\n\t\t}\n\t\tfor _, cert := range cfRootCA {\n\t\t\trootCAPool.AddCert(cert)\n\t\t}\n\t\ttlsConfig.RootCAs = rootCAPool\n\t}\n\n\tif tlsConfig.ServerName == \"\" && !tlsConfig.InsecureSkipVerify {\n\t\treturn nil, fmt.Errorf(\"either ServerName or InsecureSkipVerify must be specified in the tls.Config\")\n\t}\n\treturn tlsConfig, nil\n}\n\nfunc loadOriginCertPool(originCAPoolPEM []byte, log *zerolog.Logger) (*x509.CertPool, error) {\n\t// Get the global pool\n\tcertPool, err := loadGlobalCertPool(log)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Then, add any custom origin CA pool the user may have passed\n\tif originCAPoolPEM != nil {\n\t\tif !certPool.AppendCertsFromPEM(originCAPoolPEM) {\n\t\t\tlog.Info().Msg(\"could not append the provided origin CA to the cloudflared certificate pool\")\n\t\t}\n\t}\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/tlsconfig/origin_ca.go#L89-L125","documentation":"At the end of CreateTunnelConfig, the resulting *tls.Config is validated: TLS server-name verification requires either a ServerName (the hostname to validate the server certificate against) or InsecureSkipVerify=true. If both ServerName is empty and InsecureSkipVerify is false, crypto/tls could never verify the peer, so cloudflared rejects the config up front with this error instead of failing obscurely at handshake time.","triggerScenarios":"Calling CreateTunnelConfig(caCert, \"\") — i.e. with an empty serverName — and not setting InsecureSkipVerify on the returned config before use. Any caller (prepareTunnelConfig, probeTLSConfig, tests) that passes an empty server name without disabling verification.","commonSituations":"A config file omits the hostname/SNI field; hostname is derived from an env var or flag that is unset and yields \"\"; code builds the tunnel config before the target hostname is known and forgets to set InsecureSkipVerify for that case.","solutions":["Pass the correct hostname (e.g. the edge or origin SNI, such as your tunnel's Cloudflare hostname) as the serverName argument.","If verification must be disabled (testing only), construct the config then set tlsConfig.InsecureSkipVerify = true before use — or better, keep ServerName set and avoid disabling verification.","Fix the upstream source of the hostname (flag/config/env) so it is non-empty by the time CreateTunnelConfig is called; validate it earlier in startup."],"exampleFix":"// before\nhostname := os.Getenv(\"TUNNEL_HOSTNAME\") // may be \"\"\ntlsCfg, err := tlsconfig.CreateTunnelConfig(caPath, hostname)\n// after\nhostname := os.Getenv(\"TUNNEL_HOSTNAME\")\nif hostname == \"\" {\n\tlog.Fatal().Msg(\"TUNNEL_HOSTNAME must be set\")\n}\ntlsCfg, err := tlsconfig.CreateTunnelConfig(caPath, hostname)","handlingStrategy":"validation","validationCode":"func validateTunnelTLSInput(caCert, serverName string) error {\n\tif serverName == \"\" {\n\t\treturn errors.New(\"serverName must be non-empty (or set InsecureSkipVerify on the returned config)\")\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"tlsCfg, err := tlsconfig.CreateTunnelConfig(caCert, serverName)\nif err != nil {\n\tif strings.Contains(err.Error(), \"ServerName or InsecureSkipVerify\") {\n\t\tlog.Fatal().Msg(\"hostname/SNI missing in config; set the tunnel hostname\")\n\t}\n\tlog.Fatal().Err(err).Msg(\"failed to build tunnel TLS config\")\n}","preventionTips":["Fail fast on empty hostname flags/env vars before building TLS config.","Prefer setting ServerName over InsecureSkipVerify; never ship skip-verify in production.","Derive serverName from the tunnel hostname already validated at startup."],"tags":["tls","server-name","verification","configuration"],"backgroundTag":"missing-required-config-field","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}