fatedier/frp · critical

login to the server failed: %v. With loginFailExit enabled,

Error message

login to the server failed: %v. With loginFailExit enabled, no additional retries will be attempted

What it means

Returned from Service.Run when the initial login to frps did not succeed and loginFailExit is enabled (the default). loopLoginUntilSuccess gave up (or the context was cancelled with a cancelErr), svr.ctl is nil, so frpc stops and reports the login failure reason with a note that no retries will be attempted.

Source

Thrown at client/service.go:267

	}

	if svr.webServer != nil {
		webServer := svr.webServer
		go func() {
			log.Infof("admin server listen on %s", webServer.Address())
			if err := webServer.Run(); err != nil && !errors.Is(err, http.ErrServerClosed) {
				log.Warnf("admin server exit with error: %v", err)
			}
		}()
	}

	// first login to frps
	svr.loopLoginUntilSuccess(10*time.Second, lo.FromPtr(svr.common.LoginFailExit))
	if svr.ctl == nil {
		cancelCause := cancelErr{}
		_ = errors.As(context.Cause(svr.ctx), &cancelCause)
		svr.stop()
		return fmt.Errorf("login to the server failed: %v. With loginFailExit enabled, no additional retries will be attempted", cancelCause.Err)
	}

	go svr.keepControllerWorking()

	<-svr.ctx.Done()
	svr.stop()
	return nil
}

func (svr *Service) keepControllerWorking() {
	<-svr.ctl.Done()

	// There is a situation where the login is successful but due to certain reasons,
	// the control immediately exits. It is necessary to limit the frequency of reconnection in this case.
	// The interval for the first three retries in 1 minute will be very short, and then it will increase exponentially.
	// The maximum interval is 20 seconds.
	wait.BackoffUntil(func() (bool, error) {
		// loopLoginUntilSuccess is another layer of loop that will continuously attempt to

View on GitHub (pinned to 6c8a8d0a97)

Solutions

  1. Read the %v portion — it contains the real login error (dial timeout, auth failure, tls error) and dictates the fix.
  2. Verify serverAddr/serverPort and network reachability of frps (telnet/curl the port).
  3. Align auth settings (auth.method, auth.token) and TLS settings on both frpc and frps.
  4. If frps may start later than frpc, set loginFailExit = false so frpc retries instead of exiting.

Example fix

# before (frpc.toml)
loginFailExit = true
serverAddr = "10.0.0.1"
serverPort = 7000

# after (when frps may be temporarily down)
loginFailExit = false
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight: can we reach frps before launching frpc?
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", serverAddr, serverPort), 3*time.Second)
if err != nil { return fmt.Errorf("frps unreachable: %w", err) }
conn.Close()

Try / catch

err := svr.Run(ctx)
if err != nil && strings.Contains(err.Error(), "login to the server failed") {
    // inspect embedded cause: auth vs network; fix auth.token / serverAddr, or set loginFailExit=false and let systemd restart frpc
}

Prevention

When it happens

Trigger: Starting frpc with loginFailExit = true against an unreachable/misauthenticated frps: wrong server address/port, TLS mismatch (transport.tls vs frps proxyProtocol/tls settings), auth.token mismatch, or firewall blocking. The context cancellation cause carries the concrete login error.

Common situations: First-run misconfiguration (serverAddr typo, forgot serverPort); auth method/token mismatch after enabling token auth on frps; frps behind LB terminating TLS; running frpc as a one-shot job where infinite retry is unwanted, hence loginFailExit=true.

Related errors


AI-assisted analysis of fatedier/frp@6c8a8d0a97 (2026-08-15). Data as JSON: /api/errors/dcf9607216b59f1b. Report an issue: GitHub.