netbirdio/netbird · error

invalid signature

Error message

invalid signature

What it means

The HMAC computed over the token payload with the validator's secret does not match the signature carried in the token (compared with hmac.Equal). Either the bytes were modified in transit, or — the usual cause — the validating relay holds a different HMAC secret than the issuer, so identical payloads produce different MACs.

Source

Thrown at shared/relay/auth/hmac/v2/validator.go:46

	if err != nil {
		return fmt.Errorf("unmarshal token: %w", err)
	}

	if len(token.Payload) < minLengthUnixTimestamp {
		return errors.New("invalid payload: insufficient length")
	}

	hashFunc := token.AuthAlgo.New()
	if hashFunc == nil {
		return fmt.Errorf("unsupported auth algorithm: %s", token.AuthAlgo)
	}

	h := hmac.New(hashFunc, v.secret)
	h.Write(token.Payload)
	expectedMAC := h.Sum(nil)

	if !hmac.Equal(token.Signature, expectedMAC) {
		return errors.New("invalid signature")
	}

	timestamp, err := strconv.ParseInt(string(token.Payload), 10, 64)
	if err != nil {
		return fmt.Errorf("invalid payload: %w", err)
	}

	if time.Now().Unix() > timestamp {
		return fmt.Errorf("expired token")
	}

	return nil
}

View on GitHub (pinned to 93e97f4bf1)

Solutions

  1. Set the identical HMAC auth secret on management and the relay
  2. After rotating the secret, restart both sides and discard previously issued tokens
  3. Ensure the connection to the relay is TLS so no middlebox rewrites the frame
Defensive patterns

Strategy: try-catch

Try / catch

if err := validator.Validate(data); err != nil {
	if err.Error() == "invalid signature" {
		// deny and alert: secret mismatch between issuer and validator is the usual cause
	}
	return err
}

Prevention

When it happens

Trigger: Relay configured with a different auth secret than management; a token minted in another environment (staging vs production) presented to this relay; payload bytes altered between issuer and validator.

Common situations: Self-hosted deployments where the shared secret env/config differs between the management and relay containers; a secret rotated on one side only; tokens cached across a rotation.

Related errors


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/83b54041006fec4f. Report an issue: GitHub.