slackhq/nebula · warning

ErrOutOfWindow

ErrOutOfWindow

Error message

out of window packet

What it means

ErrOutOfWindow is declared in outside.go's underlay packet-processing path. Received handshake/data packets carry a message counter; packets whose counter falls outside the replay window (already seen or too old) are rejected with this error to prevent replay attacks.

Source

Thrown at outside.go:24

	"errors"
	"log/slog"
	"net/netip"
	"time"

	"golang.org/x/net/ipv6"

	"github.com/slackhq/nebula/firewall"
	"github.com/slackhq/nebula/header"
	"github.com/slackhq/nebula/iputil"
	"github.com/slackhq/nebula/overlay/batch"
	"golang.org/x/net/ipv4"
)

const (
	minFwPacketLen = 4
)

var ErrOutOfWindow = errors.New("out of window packet")

// readOutsidePackets processes one received underlay packet.
// Message payloads are decrypted IN PLACE, so packet must stay untouched
// by the caller until the batcher for queue q has been flushed
func (f *Interface) readOutsidePackets(via ViaSender, packet []byte, rxc *rxContext) {
	h := rxc.h
	err := h.Parse(packet)
	if err != nil {
		// Hole punch packets are 0 or 1 byte big, so lets ignore printing those errors
		// TODO: record metrics for rx holepunch/punchy packets?
		if len(packet) > 1 {
			f.messageMetrics.RxInvalid(1)
			if f.l.Enabled(context.Background(), slog.LevelDebug) {
				f.l.Debug("Error while parsing inbound packet",
					"from", via,
					"error", err,
					"packet", packet,
				)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Verify both peers share the same session key epoch; force a re-handshake if a rekey just occurred.
  2. Check the underlay network for excessive reordering/duplication (NATs, load-balanced anycast).
  3. Capture the offending packet and confirm its length is >= 4 bytes and counters are monotonic.
Defensive patterns

Strategy: validation

Validate before calling

if len(packet) < minFwPacketLen {
    return fmt.Errorf("underlay packet too short: %d", len(packet))
}

Try / catch

if errors.Is(err, outside.ErrOutOfWindow) {
    // drop packet; if rate is high, re-handshake or investigate underlay
}

Prevention

When it happens

Trigger: readOutsidePackets receives a packet whose counter is outside the sliding replay window for the session, or a too-short packet (< minFwPacketLen = 4 bytes) fails initial validation.

Common situations: Heavy packet reordering or duplication on lossy underlay networks, packets arriving after a rekey invalidated the old window, MTU/proxy mangling truncating packets below 4 bytes.

Related errors


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