slackhq/nebula · error

verify cert: %w

Error message

verify cert: %w

What it means

validateCert wraps errors from m.verifier(rc) as 'verify cert: %w'. After recombining the peer certificate, the node verifies it against its CA/network constraints (CA expiry, certificate validity window, blocked list, name/network checks). Any error from that verification is surfaced here and marks the handshake failed.

Source

Thrown at handshake/machine.go:374

		return fmt.Errorf("recombine cert: %w", err)
	}

	if !bytes.Equal(rc.PublicKey(), m.hs.PeerStatic()) {
		m.failed = true
		return ErrPublicKeyMismatch
	}

	// Version negotiation, if the peer sent a different version and we have it, switch
	if rc.Version() != m.myVersion {
		if m.getCred(rc.Version()) != nil {
			m.myVersion = rc.Version()
		}
	}

	verified, err := m.verifier(rc)
	if err != nil {
		m.failed = true
		return fmt.Errorf("verify cert: %w", err)
	}

	m.result.RemoteCert = verified
	m.remoteCertSet = true
	return nil
}

func (m *Machine) marshalOutgoing(flags msgFlags) ([]byte, error) {
	if !flags.expectsPayload && !flags.expectsCert {
		return nil, nil
	}

	var p Payload
	if flags.expectsPayload {
		if !m.indexAllocated {
			index, err := m.allocIndex()
			if err != nil {
				return nil, fmt.Errorf("%w: %w", ErrIndexAllocation, err)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Check certificate and CA expiry (`nebula-cert print -path cert.crt`) and re-issue/re-sign expired certs
  2. Sync clocks (NTP) on both hosts to fix validity-window rejections
  3. Ensure the CA bundle in the config includes the CA that signed the peer's cert
  4. Update the CA to allow the claimed subnets/groups, or reissue the peer cert with compliant network claims

Example fix

// before: expired cert
nebula-cert print -path host.crt  // Expired: 2024-01-01
// after: re-sign with longer validity
nebula-cert sign -ca ca.crt -key ca.key -name host -ip 10.0.0.2/24 -duration 8760h
Defensive patterns

Strategy: try-catch

Validate before calling

// proactively monitor expiry on all nodes
if time.Now().After(cert.ValidAfter) || time.Now().After(cert.ValidUntil) {
	return fmt.Errorf("certificate or CA out of validity window")
}

Try / catch

_, _, err := machine.ProcessPacket(pkt)
if err != nil && strings.Contains(err.Error(), "verify cert:") {
	// check cert/CA expiry, clock sync, and trusted CA bundle before retry
}

Prevention

When it happens

Trigger: ProcessPacket -> processPayload -> validateCert where the verifier rejects the recombined certificate: expired CA or cert, cert outside its validity window, certificate revoked/blocked, subnets not allowed by the CA, or internal verifier errors.

Common situations: Certificate or CA passed its expiry (common after forgetting to rotate nebula certs), clock skew between hosts making the validity window invalid, certs signed by a CA no longer in the trusted set, subnet claims exceeding CA limits after re-addressing.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/ea397a9f57823ed4. Report an issue: GitHub.