slackhq/nebula · error

ErrUnknownSubtype

ErrUnknownSubtype

Error message

unknown handshake subtype

What it means

ErrUnknownSubtype is returned by subtypeInfoFor when asked for pattern info for a handshake subtype number that this build does not know. It indicates a protocol negotiation mismatch: the peer referenced a handshake pattern variant that is not registered locally. The error is wrapped with the offending subtype number via fmt.Errorf.

Solutions

  1. Upgrade this library so both peers support the same set of handshake subtypes
  2. Pin both deployments to a version with matching pattern tables
  3. If the packet is unexpected or untrusted, drop the connection and log the peer address

Example fix

// before: peer negotiated subtype 99 (unsupported here)
// after: align versions and configure both peers to an agreed subtype
$ go get github.com/example/mesh@v1.9.0 // adds subtype 99 support
// or configure peer to use subtype 1 (XX-like pattern)
Defensive patterns

Strategy: validation

Validate before calling

if _, err := handshake.SubtypeInfoFor(subtype); err != nil {
    // reject or negotiate down before starting the handshake
    return fmt.Errorf("peer requested unsupported subtype %d", subtype)
}

Type guard

func subtypeSupported(subtype byte) bool {
    _, err := handshake.SubtypeInfoFor(subtype)
    return err == nil
}

Try / catch

info, err := handshake.SubtypeInfoFor(hdr.Subtype)
if errors.Is(err, handshake.ErrUnknownSubtype) {
    conn.Close()
    log.Printf("unsupported handshake subtype %d from %s", hdr.Subtype, conn.RemoteAddr())
    return
}

Prevention

When it happens

Trigger: subtypeInfoFor(99) in handshake/patterns.go:53 has no entry for the given subtype byte from an incoming packet's header; covered by patterns_test.go:45.

Common situations: Peer runs a newer/older library version supporting additional handshake subtypes; a corrupted or attacker-crafted packet carries a bogus subtype byte; misconfigured listeners speaking a different pattern variant.

Understand the failure class

Related errors


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

Appendix: source

Thrown at handshake/errors.go:13

package handshake

import "errors"

var (
	ErrInitiateOnResponder     = errors.New("initiate called on responder")
	ErrInitiateAlreadyCalled   = errors.New("initiate already called")
	ErrInitiateNotCalled       = errors.New("initiate must be called before ProcessPacket for initiators")
	ErrPacketTooShort          = errors.New("packet too short")
	ErrPublicKeyMismatch       = errors.New("public key mismatch between certificate and handshake")
	ErrIncompleteHandshake     = errors.New("handshake completed without receiving required content")
	ErrMachineFailed           = errors.New("handshake machine has failed")
	ErrUnknownSubtype          = errors.New("unknown handshake subtype")
	ErrMissingContent          = errors.New("expected handshake content but message was empty")
	ErrUnexpectedContent       = errors.New("received unexpected handshake content")
	ErrInvalidRemoteIndex      = errors.New("peer sent an invalid index in handshake payload")
	ErrIndexAllocation         = errors.New("failed to allocate local index")
	ErrNoCredential            = errors.New("no handshake credential available for cert version")
	ErrAsymmetricCipherKeys    = errors.New("noise produced only one cipher key")
	ErrMultiMessageUnsupported = errors.New("multi-message handshake patterns are not yet supported by the manager")
	ErrSubtypeMismatch         = errors.New("packet subtype does not match handshake machine subtype")
)

View on GitHub (pinned to dd8f660c0a)