{"record":{"id":"cf27f0ac6663cc87","repo":"grpc/grpc-go","slug":"clientconn-s-authority-from-transport-creds-q-and","errorCode":null,"errorMessage":"ClientConn's authority from transport creds %q and dial option %q don't match","messagePattern":"ClientConn's authority from transport creds %q and dial option %q don't match","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"clientconn.go","lineNumber":1959,"sourceCode":"func (cc *ClientConn) initAuthority() error {\n\tdopts := cc.dopts\n\t// Historically, we had two options for users to specify the serverName or\n\t// authority for a channel. One was through the transport credentials\n\t// (either in its constructor, or through the OverrideServerName() method).\n\t// The other option (for cases where WithInsecure() dial option was used)\n\t// was to use the WithAuthority() dial option.\n\t//\n\t// A few things have changed since:\n\t// - `insecure` package with an implementation of the `TransportCredentials`\n\t//   interface for the insecure case\n\t// - WithAuthority() dial option support for secure credentials\n\tauthorityFromCreds := \"\"\n\tif creds := dopts.copts.TransportCredentials; creds != nil && creds.Info().ServerName != \"\" {\n\t\tauthorityFromCreds = creds.Info().ServerName\n\t}\n\tauthorityFromDialOption := dopts.authority\n\tif (authorityFromCreds != \"\" && authorityFromDialOption != \"\") && authorityFromCreds != authorityFromDialOption {\n\t\treturn fmt.Errorf(\"ClientConn's authority from transport creds %q and dial option %q don't match\", authorityFromCreds, authorityFromDialOption)\n\t}\n\n\tendpoint := cc.parsedTarget.Endpoint()\n\tif authorityFromDialOption != \"\" {\n\t\tcc.authority = authorityFromDialOption\n\t} else if authorityFromCreds != \"\" {\n\t\tcc.authority = authorityFromCreds\n\t} else if auth, ok := cc.resolverBuilder.(resolver.AuthorityOverrider); ok {\n\t\tcc.authority = auth.OverrideAuthority(cc.parsedTarget)\n\t} else if strings.HasPrefix(endpoint, \":\") {\n\t\tcc.authority = \"localhost\" + encodeAuthority(endpoint)\n\t} else {\n\t\tcc.authority = encodeAuthority(endpoint)\n\t}\n\treturn nil\n}\n","sourceCodeStart":1941,"sourceCodeEnd":1976,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/clientconn.go#L1941-L1976","documentation":"initAuthority determines the channel authority from three sources: WithAuthority dial option, transport credentials' ServerName, and the dial target endpoint. If both WithAuthority and the credentials specify a non-empty server name and they disagree, NewClient/Dial fails (clientconn.go:1958-1959). Mismatched authority would break TLS verification and routing, so it is rejected up front.","triggerScenarios":"Combining grpc.WithAuthority(\"a.example\") with transport credentials whose ServerName is \"b.example\" (e.g., credentials.NewClientTLSFromFile or NewTLS with a different server name, possibly after OverrideServerName).","commonSituations":"Setting WithAuthority for SNI/routing while the TLS creds carry a different server name; copy-paste of dial options from another target; rotating certs/target and updating only one of the two.","solutions":["Make WithAuthority and the credentials' ServerName identical.","Drop one of them: use only transport credentials to derive authority, or only WithAuthority, so there is no value to disagree.","If you need to override, call OverrideServerName on the credentials to match the WithAuthority value."],"exampleFix":"// before\ncreds := credentials.NewClientTLSFromCert(caPool, \"server.example\")\ncc, err := grpc.NewClient(addr, grpc.WithTransportCredentials(creds), grpc.WithAuthority(\"other.example\"))\n// after\ncc, err := grpc.NewClient(addr, grpc.WithTransportCredentials(creds)) // authority derived from creds\n// or, if overriding:\ncreds := credentials.NewClientTLSFromCert(caPool, \"override.example\")\ncc, err := grpc.NewClient(addr, grpc.WithTransportCredentials(creds), grpc.WithAuthority(\"override.example\"))","handlingStrategy":"validation","validationCode":"func authoritiesAgree(creds credentials.TransportCredentials, authority string) error {\n\tif creds == nil { return nil }\n\tname := creds.Info().ServerName\n\tif name != \"\" && authority != \"\" && name != authority {\n\t\treturn fmt.Errorf(\"creds ServerName %q != WithAuthority %q\", name, authority)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"cc, err := grpc.NewClient(target, grpc.WithTransportCredentials(creds), grpc.WithAuthority(auth))\nif err != nil && strings.Contains(err.Error(), \"authority from transport creds\") {\n    // reconcile creds.ServerName and the WithAuthority value\n}","preventionTips":["Derive authority from a single source: either credentials or WithAuthority, not both.","When overriding, call OverrideServerName on the credentials to match WithAuthority.","Centralize dial-option construction so creds and authority stay in sync across targets."],"tags":["go","grpc","dial","tls","authority","config"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}