rancher/rancher · critical

Certificate chain is not complete, please check if all neede

Error message

Certificate chain is not complete, please check if all needed intermediate certificates are included in the server certificate (in the correct order) and if the cacerts setting in Rancher either contains the correct CA certificate (in the case of using self signed certificates) or is empty (in the case of using a certificate signed by a recognized CA). Certificate information is displayed above. error: %s

What it means

Produced during rancher-agent startup in cmd/agent/main.go: the agent probes the server URL with a plain http.Client (system trust store) and, when the TLS handshake fails with 'x509: certificate signed by unknown authority', wraps it in this remediation message. It means the agent host could not build a chain from the server certificate to a trusted root: intermediates are missing from the served chain, or the Rancher cacerts setting does not carry the right CA. The agent then reconnects with InsecureSkipVerify to dump certificate details for diagnosis.

Source

Thrown at cmd/agent/main.go:181

			systemStoreConnectionCheckRequired = false
		}
		transport.CloseIdleConnections()
	} else if cluster.CAStrictVerify() {
		logrus.Errorf("Strict CA verification is enabled but encountered error finding root CA")
		os.Exit(1)
	}

	if systemStoreConnectionCheckRequired {
		// Check if secure connection can be made successfully
		var httpClient = &http.Client{
			Timeout: time.Second * 5,
		}
		_, err = httpClient.Get(server)
		if err != nil {
			if strings.Contains(err.Error(), "x509:") {
				certErr := err
				if strings.Contains(err.Error(), "certificate signed by unknown authority") {
					certErr = fmt.Errorf("Certificate chain is not complete, please check if all needed intermediate certificates are included in the server certificate (in the correct order) and if the cacerts setting in Rancher either contains the correct CA certificate (in the case of using self signed certificates) or is empty (in the case of using a certificate signed by a recognized CA). Certificate information is displayed above. error: %s", err)
				}
				if strings.Contains(err.Error(), "certificate has expired or is not yet valid") {
					certErr = fmt.Errorf("Server certificate is not valid, please check if the host has the correct time configured and if the server certificate has a notAfter date and time in the future. Certificate information is displayed above. error: %s", err)
				}
				if strings.Contains(err.Error(), "because it doesn't contain any IP SANs") || strings.Contains(err.Error(), "certificate is not valid for any names, but wanted to match") || strings.Contains(err.Error(), "cannot validate certificate for") {
					certErr = fmt.Errorf("Server certificate does not contain correct DNS and/or IP address entries in the Subject Alternative Names (SAN). Certificate information is displayed above. error: %s", err)
				}
				insecureClient := &http.Client{
					Timeout: time.Second * 5,
					Transport: &http.Transport{
						TLSClientConfig: &tls.Config{
							InsecureSkipVerify: true,
						},
					},
				}
				res, err := insecureClient.Get(server)
				if err != nil {
					logrus.Errorf("Could not connect to %s: %v", server, err)

View on GitHub (pinned to 932558d4e6)

Solutions

  1. Redeploy the server certificate as a full chain: leaf first, then intermediate(s), in the correct order
  2. For self-signed certs, set the Rancher cacerts setting to the exact CA certificate that signed the chain; for public CA certs, leave cacerts empty
  3. Check the certificate dump the agent prints above the error to confirm served chain and ordering
  4. If a proxy intercepts TLS, add its root CA to the agent host trust store

Example fix

# before: server cert contains only the leaf
server.crt = <leaf>

# after: full chain in order
server.crt = <leaf>
<cintermediate>
<root-optional>
Defensive patterns

Strategy: validation

Validate before calling

// Verify the served chain against the system roots before deploying agents.
conn, err := tls.Dial("tcp", host, &tls.Config{})
if err != nil {
    log.Fatalf("TLS verification failed, fix chain/cacerts first: %v", err)
}
conn.ConnectionState().PeerCertificates // chain as served

Type guard

func isIncompleteChainErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "certificate signed by unknown authority")
}

Try / catch

if _, err := httpClient.Get(server); err != nil {
    if isIncompleteChainErr(err) {
        // deployment guardrail: do not start agents; fix server chain or cacerts setting
    }
}

Prevention

When it happens

Trigger: Agent registration/connect against a server URL where TLS serves an incomplete chain (leaf without intermediates, or wrong intermediate order), or Rancher's cacerts setting holds a CA that did not sign the served certificate.

Common situations: Public CA-issued certs deployed as leaf-only (Go does not use the system intermediate store the same way browsers do); self-signed certs rotated without updating the cacerts setting; corporate TLS-intercepting proxies re-signing traffic with an unknown root; load balancer (nginx/traefik) configured without the intermediate bundle.

Understand the failure class

Related errors


AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16). Data as JSON: /api/errors/bdf9a15615df963e. Report an issue: GitHub.