diff --git a/agent/consul/rpc.go b/agent/consul/rpc.go index 199df8d299..95e8a322e6 100644 --- a/agent/consul/rpc.go +++ b/agent/consul/rpc.go @@ -315,7 +315,11 @@ func (s *Server) getLeader() (bool, *metadata.Server) { func (s *Server) forwardDC(method, dc string, args interface{}, reply interface{}) error { manager, server, ok := s.router.FindRoute(dc) if !ok { - s.logger.Printf("[WARN] consul.rpc: RPC request for DC %q, no path found", dc) + if s.router.HasDatacenter(dc) { + s.logger.Printf("[WARN] consul.rpc: RPC request to DC %q is currently failing as no server can be reached", dc) + return structs.ErrDCNotAvailable + } + s.logger.Printf("[WARN] consul.rpc: RPC request for unkown DC %q", dc) return structs.ErrNoDCPath } diff --git a/agent/router/router.go b/agent/router/router.go index 426ca16283..0c3ac8f47e 100644 --- a/agent/router/router.go +++ b/agent/router/router.go @@ -356,6 +356,14 @@ func (r *Router) GetDatacenters() []string { return dcs } +// HasDatacenter checks whether dc is defined in WAN +func (r *Router) HasDatacenter(dc string) bool { + r.RLock() + defer r.RUnlock() + _, ok := r.managers[dc] + return ok +} + // datacenterSorter takes a list of DC names and a parallel vector of distances // and implements sort.Interface, keeping both structures coherent and sorting // by distance. diff --git a/agent/structs/errors.go b/agent/structs/errors.go index dcd2137c56..9d04b1ed56 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -8,6 +8,7 @@ import ( const ( errNoLeader = "No cluster leader" errNoDCPath = "No path to datacenter" + errDCNotAvailable = "Remote DC has no server currently reachable" errNoServers = "No known Consul servers" errNotReadyForConsistentReads = "Not ready to serve consistent reads" errSegmentsNotSupported = "Network segments are not supported in this version of Consul" @@ -22,6 +23,7 @@ var ( ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) ErrSegmentsNotSupported = errors.New(errSegmentsNotSupported) ErrRPCRateExceeded = errors.New(errRPCRateExceeded) + ErrDCNotAvailable = errors.New(errDCNotAvailable) ) func IsErrNoLeader(err error) bool {