slackhq/nebula · error

error creating IP: %s

Error message

error creating IP: %s

What it means

service.New assigns the netstack's static IPv4 address with AddProtocolAddress(nicID, pa, ...); failure is fatal and wrapped as 'error creating IP'. The address (provided via the Nebula cert/tun config) could not be installed on the NIC.

Source

Thrown at service/service.go:103

	}
	ipv4Subnet, _ := tcpip.NewSubnet(tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}), tcpip.MaskFrom(strings.Repeat("\x00", 4)))
	s.ipstack.SetRouteTable([]tcpip.Route{
		{
			Destination: ipv4Subnet,
			NIC:         nicID,
		},
	})

	ipNet := device.Networks()
	pa := tcpip.ProtocolAddress{
		AddressWithPrefix: tcpip.AddrFromSlice(ipNet[0].Addr().AsSlice()).WithPrefix(),
		Protocol:          ipv4.ProtocolNumber,
	}
	if err := s.ipstack.AddProtocolAddress(nicID, pa, stack.AddressProperties{
		PEB:        stack.CanBePrimaryEndpoint, // zero value default
		ConfigType: stack.AddressConfigStatic,  // zero value default
	}); err != nil {
		return nil, fmt.Errorf("error creating IP: %s", err)
	}

	const tcpReceiveBufferSize = 0
	const maxInFlightConnectionAttempts = 1024
	tcpFwd := tcp.NewForwarder(s.ipstack, tcpReceiveBufferSize, maxInFlightConnectionAttempts, s.tcpHandler)
	s.ipstack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpFwd.HandlePacket)

	reader, writer := device.Pipe()

	go func() {
		<-ctx.Done()
		reader.Close()
		writer.Close()
	}()

	// create Goroutines to forward packets between Nebula and Gvisor
	eg.Go(func() error {
		buf := make([]byte, header.IPv4MaximumHeaderSize+header.IPv4MaximumPayloadSize)

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Verify the IP parsed from the certificate/tun config is a valid IPv4 with correct prefix length
  2. Ensure CreateNIC succeeded for nicID before AddProtocolAddress (ordering in New)
  3. Check the wrapped error text for the specific tcpip code and fix the address source accordingly
  4. Upgrade/pin gVisor to match the stack.AddressProperties API used here

Example fix

// before
 Addr: tcpip.AddrFrom4([4]byte{10, 0, 0}) // truncated/invalid 3-byte address
// after
 Addr: tcpip.AddrFrom4([4]byte{10, 0, 0, 5}) // full valid IPv4 from cert networks
Defensive patterns

Strategy: try-catch

Validate before calling

ip, _, err := net.ParseCIDR(hostIP)
if err != nil || ip.To4() == nil {
    return fmt.Errorf("invalid IPv4 for netstack: %s", hostIP)
}

Type guard

func isIPv4WithPrefix(s string) bool {
    ip, _, err := net.ParseCIDR(s)
    return err == nil && ip.To4() != nil
}

Try / catch

svc, err := service.New(...)
if err != nil {
    if strings.Contains(err.Error(), "error creating IP") {
        log.Fatalf("failed to assign netstack address; check cert networks/tun IP: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: service.New is called with a protocol address whose NIC ID does not exist, the address format is invalid, the address is malformed (not a valid IPv4 with prefix), or a gVisor version rejects the AddressProperties configuration.

Common situations: Nebula cert encodes an invalid or overridden tun IP; address parsing upstream produced a tcpip.ProtocolAddress that gVisor rejects; running two service instances conflicting on addressing; gVisor API changes to AddProtocolAddress/AddressProperties.

Related errors


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