AdguardTeam/AdGuardHome · error

dhcpv6 ra: SetHopLimit: %w

Error message

dhcpv6 ra: SetHopLimit: %w

What it means

The DHCPv6 router advertisement (RA) server failed to set the IPv6 hop limit to 255 on its raw packet connection. Routers must send RAs with hop limit 255 per RFC 4861, so the RA initiator aborts if the socket option cannot be applied. It typically indicates the IPv6PacketConn does not support setting hop limits on this platform or socket type.

Source

Thrown at internal/dhcpd/routeradv.go:269

		return fmt.Errorf("creating packet: %w", err)
	}

	ipAndScope := ra.ipAddr.String() + "%" + ra.ifaceName
	ra.conn, err = icmp.ListenPacket("ip6:ipv6-icmp", ipAndScope)
	if err != nil {
		return fmt.Errorf("dhcpv6 ra: icmp.ListenPacket: %w", err)
	}

	defer func() {
		if err != nil {
			err = errors.WithDeferred(err, ra.Close())
		}
	}()

	con6 := ra.conn.IPv6PacketConn()

	if err = con6.SetHopLimit(255); err != nil {
		return fmt.Errorf("dhcpv6 ra: SetHopLimit: %w", err)
	}

	if err = con6.SetMulticastHopLimit(255); err != nil {
		return fmt.Errorf("dhcpv6 ra: SetMulticastHopLimit: %w", err)
	}

	msg := &ipv6.ControlMessage{
		HopLimit: 255,
		Src:      ra.ipAddr,
		IfIndex:  ra.iface.Index,
	}
	addr := &net.UDPAddr{
		IP: net.ParseIP("ff02::1"),
	}

	go func() {
		log.Debug("dhcpv6 ra: starting to send periodic RouterAdvertisement packets")
		for ra.stop.Load() == 0 {

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Run the service with CAP_NET_RAW / root privileges or on the host network so raw IPv6 socket options can be set
  2. Verify the interface supports IPv6 (has a link-local address) before enabling router advertisements
  3. Disable the RA/DHCPv6 feature if the environment cannot support raw IPv6 sockets
  4. Check kernel support for IPV6_UNICAST_HOPS on the target platform

Example fix

// before
{ ra_enabled: true } // inside unprivileged container

// after
// run container with: --cap-add=NET_RAW --net=host, or disable RA:
{ ra_enabled: false }
Defensive patterns

Strategy: validation

Validate before calling

// before enabling RA, check the interface supports IPv6 raw sockets
c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
if err != nil { /* skip RA feature */ }
p6 := ipv6.NewPacketConn(c)
if err := p6.SetHopLimit(255); err != nil { /* RA unsupported here */ }

Try / catch

// Go: treat RA init failure as non-fatal, degrade to DHCPv6-only
if err := ra.Init(); err != nil {
    log.Printf("RA disabled: %v", err)
}

Prevention

When it happens

Trigger: Calling the RA Init (via initRA) on a system where ipv6.PacketConn.SetHopLimit(255) returns an error — e.g. a non-raw socket, a platform without IPV6_UNICAST_HOPS support, or running in a container/sandbox that restricts socket options.

Common situations: Running the DHCPv6/RA service inside Docker or a restricted sandbox; running on a kernel or network stack with limited IPv6 socket option support; using a tunneled/virtual interface that doesn't accept hop-limit socket options.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/7fe6eec526e46584. Report an issue: GitHub.